My code in Apps script is taking too much time to execute - google-apps-script

If the user sets value of C2 as Message Finder then my cell should go to c77. I have such say 9-10 cases. I have added 3 cases in the code.
But, it is taking too long and my sheet shows "Running script for more than 8-10 seconds.
My aim is to reduce it to just 1-2 seconds or at least better than current situation
function getTool()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Course");
if(sheet.getRange("c2").getValue() == "Message Finder")
{
sheet.setActiveCell("Course!T95");
}
else if(sheet.getRange("c2").getValue() == "Fee Finder")
{
sheet.setActiveCell("Course!U39");
}
else if(sheet.getRange("c2").getValue() == "Fee Message")
{
sheet.setActiveCell("Course!N39");
}
}
Please help. Thanks

Still see no big problem with your code.
Though probably you can speed up the code this way:
function getTool() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Course');
var cell = sheet.getRange('c2').getValue();
if (cell == 'Message Finder') { sheet.getRange('t95').activate(); return }
if (cell == 'Fee Finder') { sheet.getRange('u39').activate(); return }
if (cell == 'Fee Message') { sheet.getRange('n39').activate(); return }
}

Related

How to prevent error throwing in Google Apps Script?

Please see the code herein under:
function binanceOrderBook() {
try {
muteHttpExceptions = true;
var workSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var mySheet = workSpreadsheet.getSheetByName('Order Books');
if(mySheet == 'Sheet'){
mySheet.activate();
} else {
mySheet = workSpreadsheet.insertSheet('Order Books', 1).activate();
}
var ui = SpreadsheetApp.getUi();
var string = 'https://api.binance.com/api/v3/depth?';
var symbolResponse = ui.prompt('Pair Name', 'Please enter the pair symbol.\n\nExamples: BTCUSDT or ETHBTC:', ui.ButtonSet.OK_CANCEL);
var symbolButton = symbolResponse.getSelectedButton();
if(symbolButton == ui.Button.CANCEL){return}
var mySymbol = symbolResponse.getResponseText();
mySymbol = mySymbol.toUpperCase();
string = string + "symbol=" + mySymbol;
var limitResponse = ui.prompt('Limit:', 'Please enter Limit (Period Quantity).\nValid limits are:5, 10, 20, 50, 100, 500, 1000. \n Default limit is 100.\n You can leave it blank and simply click OK.', ui.ButtonSet.OK_CANCEL);
if(limitResponse.getSelectedButton() == ui.Button.CANCEL){return}
var myLimit = Number(limitResponse.getResponseText());
if(myLimit != 5 && myLimit != 10 && myLimit != 20 && myLimit != 50 && myLimit != 100 && myLimit != 500 && myLimit != 1000){myLimit = 100;}
string = string + "&limit=" + myLimit;
var myDate = new Date().toUTCString();
var jsonOrderBookData = JSON.parse(UrlFetchApp.fetch('https://api.binance.com/api/v3/depth?symbol=' + mySymbol + '&limit=' + myLimit));
reporter(jsonOrderBookData);
} catch (e){
exceptionHandler(e)
}
}
The problem I have is to run UrlFetchApp.fetch again when it encounters an error. I need to run it several times to get the result. So, I need to prevent the script from stopping when an error (code -1003) occurs, but how can I do that?
EDIT: There is a function windows.onerror in javascript which can be set to prevent the program from stopping. Is it useable in GAS? if yes, how? if No, is there a similar solution for GAS?
You could call binanceOrderBook() from within your catch statement. E.g.
...
} catch (e){
binanceOrderBook()
exceptionHandler(e)
}
Of course you probably should have some condition that exits the function if a certain error occurs, or if you know that the function needs to run no more than x number of times you could check that it has run less than x times before executing. For example,
const maxValue = 10 // whatever the max number of executions should be
function binanceOrderBook(executions) {
if (executions >= maxValue) return;
try {
...
} catch(e) {
binanceOrderBook((executions || 0) + 1));
exceptionHandler(e); // note that I am including this here because it's in your original example, but as it is written now, exception handler won't be called until binanceOrderBook executes without an error.
}
}
[Edit] To answer your second question, there is no equivalent to window.onerror that I know of in GAS. However, window.onerror is a global event handler and so would affect errors thrown by any functions defined in your project. To address a concern with a single function call like this, you are better off using a try catch statement as you have.

Missing ) after formal parameters. (line 1, file "Code")

I am trying to make a count down clock using a user input to start it on Google Apps Script (Which uses JavaScript). And I'm getting the error (I think it is Syntax):
"Missing ) after formal parameters. (line 1, file "Code")"
Here is my code:
function COUNTD(Browser.inputBox(prompt))
{
var clock = Browser.inputBox("Intiate countdown sequence?");
if(clock == "yes")
{
return("T - 30 minutes and counting...");
}
if(count == "abort")
{
return("Countdown aborted")
}
}
I know there are multiple variations of this question, but I couldn't user the answers given for those and apply them to mine.
Am I just being really stupid?
I think what you need here is something like this:
function COUNTD(bInputBox)
{
var clock = bInputBox("Intiate countdown sequence?");
if(clock == "yes")
{
return("T - 30 minutes and counting...");
}
if(count == "abort")
{
return("Countdown aborted")
}
}
COUNTD(Browser.inputBox);

Google sheets script always returning same respone

Still quite new to this.
I have written a function:
function maxHousing(actualCost,allowedCost){
if (actualCost == ""){
return "";
}
if (parseInt(actualCost) <= parseInt(allowedCost)){
return actualCost;
}
else{
return allowedCost;
}
}
I then have a field in my sheet with the formula:
=ARRAYFORMULA(
if(
row(Parents!A:A)=1,
"Allowed Housing",
maxHousing(Parents!D1:D,Allowances!B6)
)
)
This function always returns allowedCost, no matter what I make actualCost.
I'm clearly doing something really obviously wrong here!

Does "e.namedValues('')" pull in empty results in an array or only the answered fields?

We are working to create a script that will take the information from a Google Form.
We have a Form that has four unique, multiple choice questions, containing the same title and response options:
Title = Incident Type
Reponse = Accidental or Stolen
But are separated by previous answer paths (meaning 3 of them will be unanswered on every form submission). When this form is written to a sheet the ones that were not answered are empty leaving the one that was with the value we are trying to obtain.
Here's a link to our Google Form for reference. The question that ia asked is "Incident Type", it is asked to the person once, in the answer path, but the form has it listed 4 times.
https://docs.google.com/forms/d/e/1FAIpQLSffaHkwQdfOE1e52Lkq1Eob1SyIb4O3po852NpZmVPCg3CNxA/viewform?usp=sf_link
The information is coming from a Googel Form, but the script is running on a Google Sheet, which is exporting to a Google Doc.
The question we have: Does e.namedValues['question title'] pull in the empty results in an array or only the answered question?
Here is an example of our code:
function createReport(e) {
/*ADD VARIABLES HERE*/
var incidentNumber = e.values[9];
var incidentType = e.namedValues['Incident Type'];
var folder = DriveApp.getFolderById('XXX');
var reportdoc = DriveApp.getFileById('XXX').makeCopy('Device Damage/Loss Report for ' + studentName, folder);
//Load and Open document for editing
var editReport = DocumentApp.openById(reportdoc.getId())
var tables = editReport.getBody().getTables();
/*EDIT TABLES BEYOND HERE*/
**//Incident Cost for Type Table Modification
if (incidentType == 'Accidental Damage') {
if (incidentNumber == '1st Incident') {
tables[4].getCell(1, 0).clear();
tables[4].getCell(1, 0).appendListItem('').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == '2nd Incident') {
tables[4].getCell(2, 0).clear();
tables[4].getCell(2, 0).appendListItem('').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == '3rd Incident') {
tables[4].getCell(3, 0).clear();
tables[4].getCell(3, 0).appendListItem('').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == 'Not Covered') {
return;
}
} else if (incidentType == 'Stolen') {
if (incidentNumber == '1st Incident') {
tables[4].getCell(1, 2).clear();
tables[4].getCell(1, 2).appendListItem('1st Incident: $25').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == '2nd Incident') {
tables[4].getCell(2, 2).clear();
tables[4].getCell(2, 2).appendListItem('').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == '3rd Incident') {
tables[4].getCell(3, 2).clear();
tables[4].getCell(3, 2).appendListItem('').setGlyphType(DocumentApp.GlyphType.SQUARE_BULLET);
}
else if (incidentNumber == 'Not Covered') {
return;
}
} else {
return;
}**

Mail merge: can't append images from template

I'm trying to create a mail merge function to create a document based on a simple template.
I tried to use the following function to copy the template elements but I'm having problems with the (inline) images, they appear always as PARAGRAPH and not INLINE_IMAGE and the following icon appears instead of the images:
Here's the code:
function appendToDoc(src, dst) {
// iterate accross the elements in the source adding to the destination
for (var i = 0; i < src.getNumChildren(); i++) {
appendElementToDoc(dst, src.getChild(i));
}
}
function appendElementToDoc(doc, object)
{
var element = object.copy();
var type = object.getType();
if (type == DocumentApp.ElementType.PARAGRAPH) {
doc.appendParagraph(element);
} else if (type == DocumentApp.ElementType.TABLE) {
doc.appendTable(element);
} else if (type== DocumentApp.ElementType.INLINE_IMAGE) { // This is never called :(
var blob = element.asInlineImage().getBlob();
doc.appendImage(blob);
}
}
Any ideas on how to solve this? Thanks in advance!
As per my knowledge, inline images are included in a paragraph so we have to check for Image type in the Paragraph.
So the code for checking that would be this way:
if (type == DocumentApp.ElementType.PARAGRAPH) {
if (element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
var blob = element.asParagraph().getChild(0).asInlineImage().getBlob();
doc.appendImage(blob);
}
else doc.appendParagraph(element.asParagraph());
}
Hope that helps!