Scripts Running Slowly - google-apps-script

My scripts each take over a minute to run. They accept triggers from spreadsheet, so the longer they take to run, the more executions build up, and I've started getting failures due to "simultaneous invocations."
I'm running two AutoFill functions (see sample) OnChange, and one script that populates drop-down data validations OnEdit.
function accountCreationAutoFill(e){
Logger.log(e.changeType);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Account Creation Sheet")
if(e.changeType=='INSERT_ROW'){
var rules = sheet.getConditionalFormatRules();
var needsSourceRange = sheet.getRange("AccountCreationNeedsFormula")
var needsDestination = sheet.getRange("AccountCreationNeedsAutoFill")
var contactSourceRange = sheet.getRange("AccountCreationContactFormula")
var contactDestination = sheet.getRange("AccountCreationContactAutoFill")
needsSourceRange.autoFill(needsDestination, SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES)
contactSourceRange.autoFill(contactDestination,SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES)
sheet.clearConditionalFormatRules();
sheet.setConditionalFormatRules(rules);}
}
I haven't tried anything. I'm new to coding, and it took everything I have just to write the scripts and get them to work in the first place. I don't know how to troubleshoot this issue.

Combining all functions I wanted to run On Change into one script, so I'm only running one OnChange trigger, shortened average run time by 75%.

Related

Google Apps Script copies spreadsheet every time I run the script

I'm trying to write a script that executes a function every time I open the spreadsheet the script is linked to.
But now every time I run the function, a copy of the spreadsheet is created and that definitely shouldn't happen.
I'm not sure if it might have to do with the triggers or type of deployment I set. I put a screenshot of the trigger here.
As the type of deployment I put web app.
The code in the script is pretty simple because I didn't want to go forward yet when the error is still happening. It looks like this:
function mediaplan() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s_week = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Quick view - Week");
var s_month = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Quick view - Month");
var test = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
var currentWeek = Utilities.formatDate(new Date(), "GMT", "w");
console.log(currentWeek);
}
It would be great if someone could tell me what I did wrong or if it's an error by Google.
Thanks in advance!

Running a similar App Scripts code on Multiple Sheets

Just started to use App Scripts recently (Beginner programmer here).
I'm trying to automate the creation of a column + transposition of data from column B to newly created column C.
It's working fine, but when I try to replicate the script on multiple sheets, only one of the script works.
Below is my code (I tried to duplicate my constants to replicate the first script but then the first script does not work anymore. I guess I'm doing it the wrong way) :
// First script working fine.
const ss_1 = SpreadsheetApp.getActiveSpreadsheet();
const sheet_1 = ss_1.getSheetByName('Marketing Report');
function insertColumn() {
const range_1 = sheet_1.getRange('B1:B300').getValues();
const newrange_1 = sheet_1.getRange('C1:C300');
const tmp_1 = new Date();
const yesterday_1 = new Date(tmp_1.setDate(tmp_1.getDate()-1));
sheet_1.insertColumnAfter(2);
newrange_1.setValues(range_1);
sheet_1.getRange('B2').setValue(yesterday_1).setNumberFormat("MMMM");
}
// Second script, I tried to duplicate my constants to replicate the first script but then the first script does not work anymore. I guess I'm doing it the wrong way
const ss_2 = SpreadsheetApp.getActiveSpreadsheet();
const sheet_2 = ss_2.getSheetByName('Sales Report');
function insertColumn() {
const range_2 = sheet_2.getRange('C1:C150').getValues();
const newrange_2 = sheet_2.getRange('D1:D150');
const tmp_2 = new Date();
const yesterday_2 = new Date(tmp_2.setDate(tmp_2.getDate()-1));
sheet_2.insertColumnAfter(3);
newrange_2.setValues(range_2);
sheet_2.getRange('C2').setValue(yesterday_2).setNumberFormat("MMMM");
}
Any help would be highly appreciated !
First of all, try to rename one of the functions in your script since they both have the same name. Don't forget to hit save. Please take note that Google Apps Script can run one function at a time (not including triggers). You can toggle through your functions through the dropdown menu (between the "Debug" and "Execution Log" buttons) to change to the function you would like to run. Make sure that both functions have different names.

Gapps Script in Google Sheet Is Not Scrolling No Matter What I Do

I am having troubles make Gapps Script scroll the window.
Basically, I want to send the user to the first non blank row from the buttom. My sheet has around 24000 rows. The first non blank row from the bottom is on 23500 row.
I'm using this script but not matter how many time I flush, nothing happens.
I am correctly getting the address of the lastFilledRow... It's just the sheet which never scrolls.
My code is:
function go_to_last_row() {
var ss = SpreadsheetApp.openById('abc.....')
var sheet = ss.getSheetByName('All Leads')
var lastRow = sheet.getMaxRows()
Logger.log(lastRow)
sheet.getRange('A'+lastRow).activate()
SpreadsheetApp.flush()
var lastFilledRow = sheet.getActiveCell().getNextDataCell(SpreadsheetApp.Direction.UP).activate().getA1Notation()
SpreadsheetApp.flush()
Utilities.sleep(3000)
sheet.setActiveRange(sheet.getRange(lastFilledRow)).setValue('hello')
SpreadsheetApp.flush()
Logger.log(lastFilledRow)
Logger.log('done')
}
Any ideas how to force the window to actually scroll? I even set the value "hello" correctly, but still, the cursor never goes to that cell....
Use SpreadsheetApp.getActive(). For some reason, SpreadsheetApp.openById() doesn't provide the same privileged context that container-bound scripts afford. This is actually documented by Google, but in a relatively cryptic way
Functions that are run in the context of a spreadsheet can get a reference to the corresponding Spreadsheet object by calling this function.
As a result of your question, I now interpret that to mean that the other open methods (those that don't include "Active") will not give you that reference to the corresponding Spreadsheet.
This is an abridged version of your code. Works with getActive(), but not openById().
function go_to_last_row() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('All Leads');
var lastRow = sheet.getMaxRows();
sheet.getRange('A'+lastRow).activate();
}

On Change Trigger Not Running Script On Change

I have a script to update named ranges when new rows of data are added to the spreadsheet in question:
function updateNamedRanges() {
// get to the right place
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('ga weekly data pull');
//now update the named ranges if they have changed in length
var openEnded = ["gaCampaign", "gaMedium", "gaSource", "gaSubscriptions", "gaUsers", "gaWeek"];
for(i in openEnded) {
var r = ss.getRangeByName(openEnded[i]);
var rlr = r.getLastRow();
var s = r.getSheet();
var slr = s.getMaxRows();
if(rlr==slr ) continue; // ok as is-skip to next name
var rfr = r.getRow();
var rfc = r.getColumn();
var rnc = r.getNumColumns();
var rnr = slr - rfr + 1;
ss.removeNamedRange(openEnded[i]);
ss.setNamedRange( openEnded[i], s.getRange(rfr, rfc, rnr, rnc ));
}
sheet.getRange("D2").setValue(0); // this gets all the formulas in the sheet to update - just changing any cell
}
Then, within Aps Script editor I go Resources > Current Projects Triggers > Run updateNamedRanges > From Spreadsheet > On change.
Now, if I manually add in a row of data the script runs - great!
But I'm pulling in data with the Google Analytics add on. This add on expands the tab in question when the length of data is longer than the sheet. But when this happens the script does not update.
Is there anything I can do here?
As a backup I'm thinking if I can figure out how to get GAS to add a row from the bottom of the sheet that might do it but that seems like a workaround. Before I go down that path is there a better way?
as you found out, apps script triggers only work when apps script does the changes. yea its lame. if an api outside of apps script modifies the sheet, they wont trigger.
your only option is to use a time trigger to detect a change and process the entire sheet again (since you dont know what changed). One way to achieve this more efficiently is to remember (in a script property) the last modified date from triggers. then a 1minute time trigger checks if modified date is now bigger than the last one saved. if so process the entire sheet.
Run it on a time trigger that runs every minute until Google addresses the issues of not catching the on change event and/or not being able to define open-ended named ranges.
Edited for running the script on open
To keep the sheet from recalculating everytime it is opened whether needed or not.
above the loop place:
var recalc = false;
within the loop below if(rlr==slr ) continue;
recalc = true;
recalculate the sheet only if necessary:
if(recalc) {sheet.getRange("D2").setValue(0)};

Why doesn't the trigger work for the script running a function on my google spreadsheet?

So I'm using a script on my googledoc spreadsheet that goes through a column and counts a certain number of occurrences of specified formatting. (i.e. in my spreadsheet "=myFunction()")
The function works fine, but my problem is despite setting up a trigger to run the script "onEdit", it never does it. I have to open the script up and save it each time I want it to update on my spreadsheet.
I've been looking up for hours but no one seems to have my question. There are no errors sent by the notifications. The code (though I don't think it's terribly relevant) for my function is:
function CountIfNotStrikeThrough2()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = ss.getActiveSheet();
var mydatarange = mysheet.getRange(1,1,390,1);
var numRows = mydatarange.getLastRow();
var rowindex = mydatarange.getRowIndex();
var columnindex = mydatarange.getColumnIndex();
var total =0;
for(i=rowindex;i<=numRows;i++)
{
if(mydatarange.offset(i-1, columnindex-1, 1, 1).isBlank() != true && mydatarange.offset(i-1, columnindex-1, 1, 1).getFontLine() != "line-through")
{
total++;
}
}
return total;
}
I know there's a thread here that has a comprehensive list of when the onEdit trigger doesn't activate. (here) For example, if you setup Data Validation and select an item from the list of values in the validation, it doesn't trigger the onEdit function.
Besides that, could you try a simple trigger instead of installable? This is to say, instead of explicitly associating CountIfNotStrikeThrough2() to the onEdit trigger, please try re-naming the function to "onEdit()" instead and see if that works. This creates an implicit or simple trigger. I've had trouble in the past with installable vs. simple triggers.
Also, please share the exact action you're performing to test the trigger.
Reference: https://developers.google.com/apps-script/understanding_triggers