After making a copy of my perfectly working google sheet, together with the script that comes with it; the script itself does not work anymore in the copy.
I go through the steps of authorizing it as an app but it seems to hang when i run it on the copy. It times out after 540 odd seconds. It seems to be having trouble with DriveApp.createFolder (exectution time 540 seconds). Yet i have not changed anything in the script, works fine on the original one.
Here is the script, im pretty sure everything is fine here, it just doesn't want to work as soon as you make a copy of it. I need to make copies of this sheet for each person in my team but i can't at the moment.
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var date = SpreadsheetApp.getActiveSheet().getRange(3,2).getValue();
var time = SpreadsheetApp.getActiveSheet().getRange(4,2).getValue();
var site = SpreadsheetApp.getActiveSheet().getRange(2,2).getValue();
// iterate through all sheets in the spreadsheet and rename them according to cell B2
for( var j = 0 ; j < sheets.length; j++) {
var sourceSheet = sheets[j];
// get contents of cell B2
var newSheetName = sourceSheet.getRange("B2").getValue();
// rename sheet
sourceSheet.setName(newSheetName);
}
// create a folder from the named SNOWSURVEYS with date
var folder = DriveApp.createFolder('SNOWSURVEYS' + '_' + date + '_'+ site);
// append ".csv" extension to the sheet name
fileName = SpreadsheetApp.getActiveSheet().getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
var folderID = folder.getId();
var folderName = folder.getName();
var ui = UiApp.createApplication().setTitle('Your files have are in your google drive in a folder called ' + folder);
var p = ui.createVerticalPanel();
ui.add(p);
p.add(ui.createAnchor('Click here to go straight to your files ',folder.getUrl()));
SpreadsheetApp.getActive().show(ui)
}
Execution transcript printscreen
Related
I am trying to have my function use three sheets within its embedded spreadsheet: two fixed sheets and one active/open sheet. I need it to read the sheet I have open because that is the sheet I am changing week to week, but it is automatically defaulting to using the first sheet rather than the sheet I have opened. I altered this function from an existing function I have that works, and on this new one I only changed the message and its assigned variables. I really know absolutely nothing about coding but have been learning so I can create a custom message from a code a previous coworker wrote. I appreciate all of the help I can get x10000
function createMessage(address, dirtrider, day, window, outby, phone) {
{ var message = 'Hello ' + address + ', welcome to IVCC\'s composting program! You\'ll be receiving weekly automated reports from this number (a weekly reminder to put your bucket out and a notification if any incorrect items were discarded into your bucket). To stop receiving these messages, reply STOP. We are currently restructuring our biking routes, therefore you may be receieving a new Dirtrider according to this message. Starting next week, you\'re assigned Dirtrider will be ' + dirtrider + ', and you\'re new bucket will arrive weekly on ' + day + '\'s sometime between ' + window + '. Please have your bucket outside your front door by ' + outby + ' on this day weekly unless notified of a change. This is an automated messaging service, so please reach out to your Dirtrider directly at ' + phone + ' with any questions or concerns about your service. Thanks for composting with us! -IVCC Team';
}
return message;
}
// function to verify numbers and messages before sending //
function PrintMessages() {
var mainsheet = SpreadsheetApp.getActiveSheet();
var data = mainsheet.getDataRange().getValues();
var contactsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Contact Sheet");
var contacts = contactsheet.getDataRange().getValues();
var messageLog_sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Message Log");
var messageLog = messageLog_sheet.getDataRange().getValues;
var mLrow = 2 //row to start at on Message Log spreadsheet
// runs through every row of active spreadsheet, i = row //
for (var i = 2; i < data.length; i++) {
// set variables based on values in sheet and create message//
var address = data[i][0];
var day = data[i][1];
var window = data[i][2];
var outby = data[i][3];
var dirtrider = data[i][4]
var phone = data[i][5]
var message = createMessage(address, dirtrider, day, window, outby, phone);
// reference seperate contact sheet, j = column //
var nresidents = contacts[i][2];
for (var j = 1; j <= nresidents; j++) {
// log address, phone number, and message function //
var address = contacts[i][0];
var number = contacts[i][j+2];
var messageArray = [[address, number, message]];
var range = messageLog_sheet.getRange(mLrow, 1, 1, 3); //ENTER COMMENTS
range.setValues(messageArray);
var mLrow = mLrow + 1;
}
}
}
I have a Google Sheet which hides some sheets from most users, but when an admin user is identified, has a menu option to show all the sheets. It calls my function showAllSheets, as follows:
function showAllSheets() {
var sheets=SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i = 0; i < sheets.length; i++){
//Show each sheet
sheets[i].showSheet();
console.log('Showing Sheet: ' + sheets[i].getName())
}
}
But this function doesn't always work. I get very mixed results. Sometimes it shows all sheets as expected. Sometimes it shows some of the sheets. Sometimes it eventually shows all or some of the sheets but only after a long delay (1 minute+) and sometimes, it does nothing at all.
I'm checking my execution time in the "Executions" section of Apps Script. This function typically executes in about 2-3 seconds and the console log contains all expected messages. It will say "completed" and still my sheets aren't showing. Sometimes it will eventually show the sheets some time after it says execution is complete and again, sometimes they never show.
I have an onOpen installable trigger and an onSelectionChange simple trigger, so at first I was concerned maybe my scripts are running into each other. However, I've confirmed I still have this issue even if I make sure all other scripts have completed before I run it.
I have no issues with .hideSheet() in my functions that hide the sheets (one being RestoreDefaultView, the other in my onOpen trigger.). They always get hidden immediately.
Here is the menu code I'm using:
var ui = SpreadsheetApp.getUi();
if (thisuser.group == 'admin') {
ui.createMenu('MyProject(Admin)')
.addSubMenu(
ui.createMenu('View')
.addItem('Restore Default Sheet View', 'restoreDefaultView')
.addItem('Show All Sheets', 'showAllSheets')
)
.addToUi();
}
What is going on and what can I do to fix it?
EDIT: Per request, here is the function that is hiding some of the sheets:
function restoreDefaultView() {
const name_Master = 'PROJECT MASTER';
const name_Lists = 'LISTS';
const name_Guide = 'GUIDE';
const name_Access = 'ACCESS';
const name_ActionForm = 'frm_Action';
const name_ProjectForm = 'frm_Project';
const name_NotesForm = 'frm_Notes';
const name_AdminForm = 'frm_Admin';
const name_GroupAdmin = 'admin_Groups';
//const id_ProjectList = '(redacted)'; // Google Drive file ID of Project List'
//const id_TaskList = ''; //Google Drive file ID of Task List
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sht_Master = ss.getSheetByName(name_Master);
var sht_Guide = ss.getSheetByName(name_Guide);
var sht_Lists = ss.getSheetByName(name_Lists);
var sht_Access = ss.getSheetByName(name_Access);
var sht_ActionForm = ss.getSheetByName(name_ActionForm);
var sht_ProjectForm = ss.getSheetByName(name_ProjectForm);
var sht_NotesForm = ss.getSheetByName(name_NotesForm);
var sht_AdminForm = ss.getSheetByName(name_AdminForm);
var sht_GroupAdmin = ss.getSheetByName(name_GroupAdmin);
//Sheets Normally Displayed
//Immediately activate Master sheet after making visible to minimize confusion
sht_Master.showSheet();
sht_Master.activate();
sht_Guide.showSheet();
//Sheets Normally Hidden
sht_Lists.hideSheet();
sht_Access.hideSheet();
sht_ActionForm.hideSheet();
sht_ProjectForm.hideSheet();
sht_NotesForm.hideSheet();
sht_AdminForm.hideSheet();
sht_GroupAdmin.hideSheet();
}
Try this:
function showAllSheets() {
var sheets=SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i = 0; i < sheets.length; i++){
sheets[i].showSheet();
SpreadsheetApp.flush();
console.log('Showing Sheet: ' + sheets[i].getName())
}
}
Having a bit of trouble using importJSON for the first time in Google Sheets. My data is importing as truncated and I can't find any way to really filter things the way I'd like.
API source: https://prices.runescape.wiki/api/v1/osrs/1h
I'm using the following command: =IMPORTJSON(B1;B2)
where B1 is the source link, and B2 references any filters I've applied. So far I have no filters.
My result is a truncated list that displays as such:
data/2/avgHighPrice 166
data/2/highPriceVolume 798801
data/2/avgLowPrice 162
data/2/lowPriceVolume 561908
data/6/avgHighPrice 182132
data/6/highPriceVolume 7
data/6/avgLowPrice 180261
data/6/lowPriceVolume 37
data/8/avgHighPrice 195209
data/8/highPriceVolume 4
data/8/avgLowPrice 192880
data/8/lowPriceVolume 40
In the examples I've seen and worked with (primarily the example provided by the Addon), it will naturally pivot into a table. I can't even achieve that, which would be workable although I'm really only looking to ping the markers avgHighPrice and avgLowPrice.
EDIT:
I'm looking for results along the lines of this:
2
6
8
/avgLowPrice
162
180261
192880
/avgHighPrice
166
182132
195209
EDIT2:
So I have one more thing I was hoping to figure out. Using your script, I created another script to pull the names and item IDs
function naming(url){
//var url='https://prices.runescape.wiki/api/v1/osrs/mapping'
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var result = []
result.push(['#','id','name'])
for (let p in eval('data.data')) {
try{result.push([p,data.item(p).ID,data.item(p).Name])}catch(e){}
}
return result
}
Object.prototype.item=function(i){return this[i]};
I'm wondering if it is possible to correlate the item Name with the Item ID from the initial pricing script. To start, the 1st script only list items that are tradeable, while the 2nd list ALL item IDs in the game. I'd essentially like to correlate the 1st and 2nd script to show as such
ID
Name
avgHighPrice
avgLowPrice
2
Cannonball
180261
192880
6
Cannon Base
182132
195209
Try this script (without any addon)
function prices(url){
//var url='https://prices.runescape.wiki/api/v1/osrs/1h'
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var result = []
result.push(['#','avgHighPrice','avgLowPrice'])
for (let p in eval('data.data')) {
try{result.push([p,data.data.item(p).avgHighPrice,data.data.item(p).avgLowPrice])}catch(e){}
}
return result
}
Object.prototype.item=function(i){return this[i]};
You can retrieve informations for naming / from mapping as follows
function naming(url){
//var url='https://prices.runescape.wiki/api/v1/osrs/mapping'
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var result = []
result.push(["id","name","examine","members","lowalch","limit","value","highalch"])
json=eval('data')
json.forEach(function(elem){
result.push([elem.id.toString(),elem.name,elem.examine,elem.members,elem.lowalch,elem.limit,elem.value,elem.highalch])
})
return result
}
https://docs.google.com/spreadsheets/d/1HddcbLchYqwnsxKFT2tI4GFytL-LINA-3o9J3fvEPpE/copy
Integrated function
=pricesV2()
https://docs.google.com/spreadsheets/d/1HddcbLchYqwnsxKFT2tI4GFytL-LINA-3o9J3fvEPpE/copy
function pricesV2(){
var url='https://prices.runescape.wiki/api/v1/osrs/mapping'
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
let myItems = new Map()
json=eval('data')
json.forEach(function(elem){myItems.set(elem.id.toString(),elem.name)})
var url='https://prices.runescape.wiki/api/v1/osrs/1h'
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var result = []
result.push(['#','name','avgHighPrice','avgLowPrice'])
for (let p in eval('data.data')) {
try{result.push([p,myItems.get(p),data.data.item(p).avgHighPrice,data.data.item(p).avgLowPrice])}catch(e){}
}
return result
}
Object.prototype.item=function(i){return this[i]};
I am writing a Google Sheets Script to save as Sheet file to a PDF. I want the File Name to be Cell A11 (which is a combination of texts from other cells). So I wrote this:
file.setName(Cell + '.pdf');
My question is: how can I define "Cell" to pull data from A11 from inside the spreadsheet.
Here. Add this function to your script.
function getFilename() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('Sheet1');
// Edit the sheet name as necessary
var cell = sheet.getRange('A11');
var filename = cell.getValue();
return filename;
}
Then change
file.setName(Cell + '.pdf');
to
file.setName(getFilename() + '.pdf');
I would like to create a button to print just a certain range of a Google Spreadsheet. I am playing arroud with .getRangeByName class but it wont work. Maybe someone can help me with some ideas?
I am playing arround with some code I found here on stackoverflow.
I am just stuck by replacing the columns and rows by a certain range name or namedRange.
All in all the result of the script below works fine for me so far.
Thanks and Regards!
function printPdf() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var gid = sheet.getSheetId();
var pdfOpts = '&size=A4&fzr=false&portrait=false&fitw=true&gridlines=false&printtitle=false&sheetnames=false&pagenum=UNDEFINED&attachment=false&gid='+gid;
var last_row = sheet.getLastRow(); var printRange = '&c1=0' + '&r1=0' + '&c2=34' + '&r2='+last_row // B2:APn var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + pdfOpts + printRange;
var app = UiApp.createApplication().setWidth(200).setHeight(50);
app.setTitle('Verze pro tisk');
var link = app.createAnchor('Zobrazit PDF', url).setTarget('_new');
app.add(link);
ss.show(app);
}