I am writing a program in the Google Spreadsheet API for Google App Script which references the display value cells in a sheet to formulate QUERY() functions, then returns the result of that formulated QUERY() function to different cells.
Because there are a lot of changing variables when formulating these query functions, (I am referencing a cell responsible for the source sheet, for the column to look for, and the data point to return,) the query functions which are formulated often have #REF or #N/A errors. Although this is easily avoidable for me, the program is intended for a client and I, therefore, have to have better-informed error messages so someone can easily figure out the issue.
In this case here, I am referencing the sheet "Utility Companies" for the column "Utility Name," then returning the corresponding "Address" value. because "Error" doesn't appear in the "Utility Name" column in the "Utility Companies" sheet, a #N/A error is thrown when trying to return the corresponding address.
I tried a try-catch statement, but it didn't seem to recognize an error:
try{
//This is assigning the assembled QUERY() formula to a cell
//(works successfully & reliably)
retrieveRange.getRange().getCell(k+1, 1).setFormula(formulaArray[k]);
} catch (e){
//Never catches an error, and therefor never logs the following-
Logger.log("Error Recognized:" + e);
}
How do I catch these errors? And furthermore, how do I report a custom error message for those errors?
Thank you so much!
Related
This may be a simple issue, but I am having some trouble with a section of code.
Here is the code:
function CreateSheet() {
function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0)
.toUpperCase() + txt.substr(1)
.toLowerCase();
});
}
var ss = SpreadsheetApp.getActive();
var templatesheet = ss.getSheetByName('Template');
//var fieldName = Browser.inputBox('Field Name', 'Insert Field Name', Browser.Buttons.OK_CANCEL);
var ui = SpreadsheetApp.getUi();
var fieldResult =
ui.prompt(
'FIELD NAME',
'Please type in the Field Name',
ui.ButtonSet.OK
)
var fieldName = toTitleCase(fieldResult.getResponseText());
var acreResult = ui.prompt('ACRES',
'Please type in the # of acres, if the # is not known just leave it blank',
ui.ButtonSet.OK
)
var acres = acreResult.getResponseText();
var url = '';
ss.insertSheet(fieldName,3,{template: templatesheet});
ss.getRange('B3:D3').activate();
ss.getCurrentCell().setValue(fieldName);
ss.getRange('E3').activate();
ss.getCurrentCell().setValue(acres);
url += '#gid=';
url += ss.getSheetId();
ss.setActiveSheet(ss.getSheetByName('Summary'));
SpreadsheetApp.setActiveSpreadsheet(ss);
ss.getRange('A5:J5').activate();
ss.getRange('A5:J5').insertCells(SpreadsheetApp.Dimension.ROWS);
The last line is where it is throwing the exception message:
Service Spreadsheets failed while accessing document with id..
If I go into the sheet itself and manually insert range 'A5:J5' then run the code it will work. What am I missing here?
Service Spreadsheets failed while accessing document with id
is usually an error message one obtains when hitting the maximum size limit for a spreadsheet
This limit is 5 000 000 cells, so it should not be the issue for your spreadsheet
However, several users experienced the same problem as you and have reported it on Google's Public Issue Tracker here or here
It is likely to be a bug and it currently being investigated by Google
Some users reported that they experience the problem only with V8 runtime
Try to disable it (Run > Disable new Apps Script runtime powered by V8), hopefully it will solve the issue temporarily
Otherwise, try to find a workaround replacing the line leading to the error
When I reproduce your script it does not error for me, this is why I can only give you some suggestions
If insertCells gives you trouble, try insertRowAfter() or similar instead
If the problem comes from ss.getRange('A5:J5'), try ss.getActiveSheet().getRange('A5:J5') or ss.getSheetByName('Summary').getRange('A5:J5')
Also, try removing the line SpreadsheetApp.setActiveSpreadsheet(ss); - you already defined ss as the active spreadsheet above, there is no need to set it to active again
I had this same problem related to insertCells. It drove me nuts for a couple of days but I finally just solved it! In case this helps someone else, here is a link to my answer as well as a copy/paste of it to be thorough.
This was a REALLY confusing issue to solve, as the errors reported by
the debugger did not point to the true culprit.
In another cell elsewhere on the sheet, I had this formula:
=SUMPRODUCT(LEN($A$5:$A)>0)
But since my inserted cells started with A5, this was causing the
error to be thrown when I would attempt the insert, if it tried to
insert ahead of A5. By removing this formula, the insert code works
perfectly every time, immediately.
So if you get this error and it is not related to having a sheet that
is too large etc., check to see if you have another formula somewhere
that is referencing the cell being inserted on.
Sometimes this error is caused by a process or calculation that was triggered by an earlier part of the script that has not completed by the time you try to insert those cells.
For example, if you have a formula that is summing a column in your summary sheet, that formula may still be calculating at the time you are trying to shift the rows that the sum formula is referencing. You can force the order of operations to complete those calculations before shifting the rows by adding SpreadsheetApp.flush(); before you insert new cells.
SpreadsheetApp.setActiveSpreadsheet(ss);
SpreadsheetApp.flush();
ss.getRange('A5:J5').activate();
ss.getRange('A5:J5').insertCells(SpreadsheetApp.Dimension.ROWS);
I had same issue.
First, you always need to make sure the sheet you are working on is an actual 'Google SpreadSheet' and not an uploaded one (for example, .xlsx or .xls).
Then use the Save as function to save the document as a Spreadsheed; this solution worked for me.
I found that a chart using the range caused this exception, remove the chart and it worked.
I ran into the same error message, with a sheet of 400 rows and 9 columns only. Inspired by the variouos proposals for solutions, I tried the following, and this did the trick:
duplicated the "orig sheet" to "copy of sheet"
deleted rows 4 to [last row] in "orig sheet" (so only 3 rows left)
copied rows 4 to [last row] from "copy of sheeet" back to "orig sheet"
and the script worked fine again :-)
(advantage: I did not have to change any formulas or scripts)
I am trying to work with data submitted by users via Google Forms. My trigger is tied to the spreadsheet on Form Submit, but when I use the following code, I get "e" returned with a NULL value and I can't do anything with it. I am submitting it through the forms and not just running a script. My spreadsheet is updating fine, but I can do anything with the values I'm getting.
function getTickets(e) {
var values = e.namedValues;
Logger.log(e);
Logger.log(values);
}
The exact error I get is:
[20-03-10 21:48:22:765 EDT] TypeError: Cannot read property 'namedValues' of undefined
at getTickets(Tickets:2:18)
The problem was reported that user was getting a nulll for event object parameter values. I suggested trying to switch back to legacy ES5 because it’s easy to do and it seems to fix many difficult to understand problems.
I'm trying to make an applet in Google Spreadsheets and Apps script that scrapes view data about youtube videos searched by users. When a user types in a search query, a new sheet should be copied from a template sheet and customized to the query. The problem I'm encountering is that when a user rapidly types in multiple queries in succession, the script would dump multiple copies of the template sheet and name them 'Copy of template 1', 'Copy of template 2' and so on, whereas the name of each sheet should be "KW: " + its associated keyword. I suspect this is because the function duplicates and renames a sheet, but if two or more instances of a function try this at nearly the same time, they target the same sheet, causing errors.
This is the culmination of what I've tried:
function main(e){
//spreadsheet=SpreadsheetApp.getActiveSpreadsheet() at the top of the function
//keyword=the string the user typed in
//...
while(true){
var random=Math.random().toString();
try{
//assign the template sheet a random name other processes will fail when they try to use it
spreadsheet.getSheetByName('template').setName(random);
//make a copy of the template
spreadsheet.getSheetByName(random).copyTo(spreadsheet);
//give the copy a proper name
spreadsheet.getSheetByName('Copy of '+random).setName("KW: "+keyword);
//reset the name of the template so other processes can use it
spreadsheet.getSheetByName(random).setName('template');
break;
}
//when a process fails, it should wait then try again
catch(e){Utilities.sleep(Math.round(random*250));}
//...
}
main is has a trigger set on edit. The above code prevents any 'Copy of template n' sheets from appearing, but it simply leaves out most of the sheets that should be produced. My guess is that the code encounters an error in the first line of the try block and loops until it times out. I'm very much at a loss as to what to do. I'd appreciate any help, thank you!
Try copying the template sheet first, then changing the name of the new sheet. Your solution runs into errors because you're modifying the template sheet, but you should really avoid doing that. With this approach, you'll never modify the template sheet.
function main(e){
//spreadsheet=SpreadsheetApp.getActiveSpreadsheet() at the top of the function
//keyword=the string the user typed in
//...
while(true){
try{
// Select the template sheet
var templateSheet = spreadsheet.getSheetByName("template");
// Set the new sheet name
var sheetName = "KW: "+keyword;
// Copy the template sheet and set name
var newSheet = templateSheet.copyTo(spreadsheet).setName(sheetName);
break;
}
//when a process fails, it should wait then try again
catch(e){Utilities.sleep(Math.round(random*250));}
//...
}
}
Granted that I don't have full knowledge of what you're doing with your script, I do have some major concerns with your approach. I don't think you should be creating a new sheet for every query. For one, that will make your data really challenging to aggregate. Secondly, since sheet names must be unique, any time someone searches for something that already has an existing sheet, your function will get stuck in the infinite while loop you set up.
I don't know what kind of data you're placing in the sheets, but you should consider trying to record the data in one sheet. Also, although your while loop works and will, in the case of errors, eventually be terminated by Google's script limitations, you should really try (1) implementing something more robust like appending a number to the sheet name and (2) properly logging the errors.
GAS novice here, but enjoying it.
Here is a data sample in a Google Sheet called "Sheet1".
I have a Google Script that formats this data, creates a new sheet called "totals by account" that sets "A1" to the formula: =QUERY(Sheet1!A:J,'select E, sum(J) group by E',0)"
This all works well, but the cell/Query gives a "Forumla parse error" message. I've seen this Query work before, but it doesn't seem to be consistent. I formatted column J to a number and "0.00" (DATA_SHEET.getRange("J1:J1000").setNumberFormat("0.00");)
Thank you for your help!
Try replacing quotes with double quotes in the query :
=QUERY(Sheet1!A:J,"select E, sum(J) group by E",0)
It would seems I am stuck with a consistant "Server Encountered an Error" when I am trying in my function to use the insertRows() call or insertRowsAfter() and then do a getRange() operation call within the range of cells newly created (like changing the font weight, or setvalues in the new cells).
When I call my function I always get a google "Server Encountered and Error".
When I call my function in debug mode, step by step: no errors!!!
I have no error logs showing when doing a catch.
I tried a Spreadsheet.flush() call before the getRange() operation, not helping.
function test() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sdebtcal = ss.getSheetByName('Debt');
var max_rows = sdebtcal.getMaxRows(); // sheet set with only 5 rows to test
sdebtcal.insertRowsAfter( max_rows , 20); // adding 20 rows
sdebtcal.getRange(max_rows+5, 1, 2, 1).setFontWeight('bold'); // trying to setFontWeight in the new range of cells
}
I have to say I tried a with a blank spreadsheet, and I do not have the problem. Only with my current large spreadsheet. Though the test sheet is a small one (2 rows to test!). Also I am not reaching any max cells limits on the spreadsheet.
Anybody with a hint? Possible bug from the spreadsheet script API with large spreadsheets?
Regards,
I discovered that problems I experienced with InsertRowsBefore() and InsertRowsAfter() disappeared if the spreadsheet wasn't open on the client side at the time the script executes. So if it's possible for you to insert the rows either from a script in a different spreadsheet or on a timed trigger, then you might find you can work around the problem. Good luck!
Here's a link to a post I made about it on the GAS forum if you want more detail and you might be interested in adding a comment to Issue 1270 about it too.