I would like to install a time based trigger on multiple Google Sheets using Google Apps Scripts and can't figure out how to do so. I know these can be added through the UI but I was hoping to find a programmatic way to do this. I have tried this code:
function initializeTrigger(sheetID){
var sheet = SpreadsheetApp.openById(sheetID);
ScriptApp.newTrigger('myLibrary.myFunction')
.forSpreadsheet(sheet)
.timeBased()
.atHour(9)
.everyDays(1)
.create();
}
function installMultipleTriggers(){
var sheetList = [sheetID1, sheetID2, sheetID3];
for (var i = 0; i < sheetList.length; i++)
{
initializeTrigger(sheetList[i]);
}
}
But when I run this I receive the error:
TypeError: Cannot find function timeBased in object SpreadsheetTriggerBuilder.
Which makes sense I guess, because according to the documentation, the SpreadsheetTriggerBuilder class doesn't have a method named timeBased()... Does anyone know how to add time-based triggers to multiple Google Sheets?
A time based trigger is independent of a sheet based trigger. Sheet based triggers respond to events that occur on the sheet, for example if you edit a cell.
I would eliminate the forSpreadsheet call in your code snippet, that should resolve your issue.
Create Spreadsheet Triggers Programatically
So I guess the issue here is that you wish to tie the triggers to a spreadsheet. I believe that only way to do that is to create the triggers from a project that is contained by the spreadsheet and you can just use ClockTriggerBuilder.
Related
I've got a master spreadsheet which people will regularly be making copies of. I've got several on edit triggers set up on the master but can't seem to keep these working on copies of the spreadsheet. Is there any way to resolve this?
to add to what ziganotschka is saying.
we can add installable triggers in the script itself and get them installed with onOpen trigger.
one time authorization is required for these to run,
for that you can create a button on the google sheet and assign onOpen function to it.
once that is clicked authorization will happen. and you shall be good to go.
Now the problem is if we ask the sheet to install trigger onOpen it will keep on installing triggers everytime the sheet opens.
a simple if logic can be a work around.
example code :
function onOpen() {
makeTriggerIfempty();
}
function makeTriggerIfempty() {
var allTriggers = ScriptApp.getProjectTriggers();
if(allTriggers.length < 1){
createTimeDrivenTriggers();
}
}
function createTimeDrivenTriggers() {
// Trigger every 2 hours.
ScriptApp.newTrigger('myFunction')
.timeBased()
.everyHours(2)
.create();
// Trigger every Monday at 08:00.
ScriptApp.newTrigger('myFunction')
.timeBased()
.onWeekDay(ScriptApp.WeekDay.MONDAY)
.atHour(8)
.create();
}
Installable triggers apply to the spreadsheet to which they were bound
Simple triggers are defined in the script
When you make a copy of a spreadsheet, the bound Apps Script will also be copied
Thus, the simple onEdit triggers contained in the script will also get copied and will work for the copied spreadsheet
All the users have to do is to run the script once manually - in order to trigger authorization flow
I am learning to use google app script. I have written code to get row number in which so far I succeeded but can't find a way to assign it to a cell or row change event trigger. Can someone help me figure out how to do this?
My code is as follows :
function onChange(event) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var currentCell = sheet.getCurrentCell();
sheet.getRange("B1").setValue(currentCell.getRow());
}
There are no "onSelect" trigger on Google Apps Script but you could use the poll technique. Basically, you will have to use a sidebar to hold client-side code that will check for the selected cell every determined time. For code examples checkout the following Q/A
How do I make a Sidebar display values from cells?
How to detect user changing sheet?
Have you installed the trigger? onChange triggers need to be explicitly hooked up because they're considered installable triggers (opposed to simple triggers, which just require saving the .gs file).
You can manage your triggers from the Menu in your Apps Script Editor:
this script stops just at the entry of the last function : addToDocument().
Until this point all is working. I presume a problem due to onEdit() and DocumentApp call?
Note that separately, my addToDocument() works perfectly.
function onEdit() {
// simple timestamp -- when a single "t" is entered in a cell, replace it with a timestamp
// see https://productforums.google.com/d/topic/docs/rC6MpQDC7n4/discussion
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var cell = SpreadsheetApp.getActiveRange();
if (cell.getValue() == "t") {
cell.setValue(new Date());
}
formatDate() // Some Date formatting using : 'SpreadsheetApp' call
mefCond() // Some conditonnal formatting using : 'SpreadsheetApp' call
doCounts() // Some numéricals opérations, using : 'SpreadsheetApp' call
//At this point the scripts enter in the following function,
//and stops on the first line. Nothing being executed.
addToDocument() // Time stamp on a document using : 'DocumentApp' call
}
Any ideas ?
Thanks for reading,
Eric :-)
When OnEdit is run manually it runs with a different set of permissions but while Triggers themselves have specific restrictions as mentioned here. From that page see..
They can modify the file they are bound to, but cannot access other
files because that would require authorization.
Please refer to this for the authorization modes and what you can do under each of them. May be line 2 below is affecting you...
The solution for you I believe is to convert your simple trigger into an installable trigger. Here are details how to install a trigger for your spreadsheet. Nothing will changes with respect to your onEdit() function, you just have to run installation code snippet once to create an installable trigger.
function createSpreadsheetEditTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('onEdit')
.forSpreadsheet(ss)
.onEdit()
.create();
}
And here are the details on permissions and other details. In here it clearly mentions that you can access other services..
For example, the installable open trigger for Google Sheets activates
whenever the spreadsheet is opened by any user who has edit access,
just like the simple onOpen() trigger. However, the installable
version can call services that require authorization. The installable
version runs with the authorization of the user who created the
trigger, even if another user with edit access opens the spreadsheet
I have written a script to clear a range of cells (B4:B8) when a specified cell (C1) is changed. However, the cells are not cleared when I edit the specified cell. Here is the script:
function onChange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Quality Control').getRange('C1');
ScriptApp.newTrigger("clearRange")
.forSpreadsheet(sheet)
.onChange()
.create();
}
function clearRange() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Quality Control');
sheet.getRange('B4:B8').clearContent();
}
The function onChange is set to run onOpen (trigger).
Any idea why this script isn't working?
Short answer
Instead of creating a trigger by code create it manually. Set your trigger to call the clearRange() directly.
Explanation
The script in the question is not working because there is a bug but rather than fixing the bug could be better to set a trigger manually otherwise a new trigger will be created every time that the spreadsheet be opened.
To create a trigger manually, follow the instructions from https://developers.google.com/apps-script/guides/triggers/installable#managing_triggers_manually
Managing triggers manually
To manually create an installable trigger through a dialog in the
script editor, follow these steps:
From the script editor, choose Resources > Current project's triggers.
Click the link that says: No triggers set up. Click here to add one now.
Under Run, select the name of function you want to trigger.
Under Events, select either Time-driven or the Google App that the script is bound to (for example, From spreadsheet).
Select and configure the type of trigger you want to create (for example, an Hour timer that runs Every hour or an On open trigger).
Optionally, click Notifications to configure how and when you will be contacted by email if your triggered function fails.
Click Save.
Comments about the code on the question
.forSpreadsheet(sheet) requires that sheet be a spreadsheet object but your code assigns a range to the sheet variable.
From https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder#onchange
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("myFunction")
.forSpreadsheet(sheet)
.onChange()
.create();
See https://developers.google.com/apps-script/troubleshooting to learn how to use the debugging tools on the Google Apps Script Editor
I'm developing new applications in google.
I have a function that is running without any problem if it's bound in the spreadsheet but when it is offline it doesn't work. That's why I saved this script in google drive in order to be called from my google spreadsheet even if it's offline.
I don't know how I link this function to my spreadsheet in order to run both offline.
function onEdit(event)
{
var DistSheet = event.source.getActiveSheet();
...
}
If you want to use a simple trigger like onEdit, it is unfortunately not possible (see the documentation: onEdit is a Simple Trigger, which is restricted to Bound scripts).
However, you can accomplish this with Installable Triggers.
Code for stand alone script
ScriptApp.newTrigger('myFunction')
// insert the file ID for the spreadsheet you'd like to edit
.forSpreadsheet('1234567890abcdefghijklmnopqrstuvwxyz')
.onEdit()
.create();
function myFunction() {
var DistSheet = event.source.getActiveSheet();
// continue script
}
Once you've added this to your script, click the right arrow ("play") icon. It will ask for the proper authorization and then should work after that.
You can see the documentation on Installable Triggers for more information.