Add button to trigger script along top bar in google sheets - google-apps-script

I have written the script below to hid all rows that have a specific box checked. I set a trigger using the clock and every 10 minutes but instead seems to run every time I check a box and it screws up the view every time I check it. I would like to change it to a manual trigger that is a button along the top bar that someone manually clicks. Can anyone help me edit it?
function onEdit(e) {
var s = SpreadsheetApp.getActive().getSheetByName('2 Week Snapshot');
s.showRows(1, s.getMaxRows());
s.getRange('C:C')
.getValues()
.forEach( function (r, i) {
if (r[0] == 1)
s.hideRows(i + 1);
});
}

As mentioned by I'-'I, the name given to your function causes your script to run when an edit is made to the sheet. From the Apps Script documentation on Simple Triggers:
To use a simple trigger, simply create a function that uses one of these reserved function names:
- onOpen(e) runs when a user opens a spreadsheet, document, presentation, or form that the user has permission to edit.
- onEdit(e) runs when a user changes a value in a spreadsheet.
- onInstall(e) runs when a user installs an add-on.
- doGet(e) runs when a user visits a web app or a program sends an HTTP GET request to a web app.
- doPost(e) runs when a program sends an HTTP POST request to a web app.
The e parameter in the function names above is an event object that is passed to the function. The object contains information about the context that caused the trigger to fire, but using it is optional.
Renaming your function to avoid binding this simple trigger will prevent edits of your sheet from triggering your function.
Documentation to look at:
Guide to Menus
Guide to Triggers

Related

Google Apps script onEdit doesn't work for Google Tables [duplicate]

I have two combo boxes in cells that are populated by ranges in the sheet. When the first one changes, I build a URL and call:
var resp = UrlFetchApp.fetch(url, {"method": "get","muteHttpExceptions":false});
And it populates a 2nd range which controls the 2nd combo box. This works just fine in debug mode. But my goal is for this to work using the onEdit mode. If the first combo box is changed, the method runs and populates the second. Using this statement:
mydoc.getActiveSheet().getRange(15, 1).setValue("Some debug message");
I have it placed throughout the method to see where it dies. I have a statement right after the UrlFetchApp.fetch() method that never writes, so I know that's where the problem is. Can you make these types of calls during events?
Again, it works just fine running it manually via the script editor, but not when called from onEdit.
I see this question where they do not allow it, but the last comment in the thread said he got it to work by attaching another custom method to onEdit. I call URLFetchApp from another method, but I tried creating a myOnEdit function, and called URLFetchApp from there, but it still fails. Not sure what he meant by manually attaching to the event...
Using a simple trigger:
function onEdit(e) {
var response = UrlFetchApp.fetch('http://www.google.com/');
Logger.log(response.getContentText());
}
I get the following error (View -> Execution transcript):
Execution failed: You do not have permission to call fetch (line 2, file "Code") [0.008 seconds total runtime]
One possible workaround is to create a installable trigger:
function myOnEdit(e) {
var response = UrlFetchApp.fetch('http://www.google.com/');
Logger.log(response.getContentText());
}
/*
In the Spreadsheet, create new trigger:
Run: myOnEdit
Events: From spreadsheet
On edit
*/

Installable trigger to fire script in a different form?

I'm trying to run a script that is connected to one form (A) when a different form (B) is submitted. I have a series of different forms that are similar and needs to run the same script, so instead of copying the code to each script I wonder if this is possible.
I successfully made an installable trigger function in A, pointing at B. I have granted permission when prompted.
When i post B, the script in A fires, and I get this in the log:
Exception: No response with ID 2_ABaOnudSFDkNQOL2Xn4fNOmT95GrTotEW8LSjxfI5qf6qceDN5hD5CHKqNT5D4G_DdONWq0 exists for this form.
at onFormAnswerSubmit(Kod:40:20)
The line (Kod:40:20) that halts is the line that fetches the posted data:
var items = e.response.getItemResponses();
Is this supposed to work or is it impossible to pass posted data from one form to a script in a different form?
Or is there something more I can do in the trigger? Like forcing a pass on of e. or something?
Here is the trigger I created:
/**
* Creates a trigger for when a different form is posted that runs a function in this script (run once)
*/
function createOtherFormTrigger() {
var formID = FormApp.openById("XXXXX"); // form B
ScriptApp.newTrigger('onFormAnswerSubmit') // a function in this script, in form A
.forForm(formID)
.onFormSubmit()
.create();
}
You need to change the logic a bit:
The function fired on trigger should be contained in the same script like the trigger.
Sample code to create a formSubmit trigger for form B:
//run this once
function createOtherFormTrigger() {
var formB = FormApp.openById("XXX");
ScriptApp.newTrigger('onFormAnswerSubmit') // a function in this script, in form B
.forForm(formB) //the active form is Form B
.onFormSubmit()
.create();
}
function onFormAnswerSubmit(e){
var formB = e.source;
var items = e.response.getItemResponses(); //items of the latest form response of form B
var formA = FormApp.openById("XXXX"); // Form A
...
// do what you need to do with form A
}
The code above will create trigger that fires when a form response for form B is being submitted. Thereby it is not important either the script is bound to form A, form B or is standalone. Actually, it might make mosst sense to implement those functions in a standalone script, to make sure that they don't interfer with other form submit triggers you might have in a form-bound script.
I had the same issue. Anywhere where I put e.response I get the same error. It looks that the only workaround is to use a stand alone script instead of a bounded script.
I just understand the problem.
So if you want to catch the response from the form submission, you need to bound your script to the form. To do that, go to your form edit view, then click the three dots, then open script editor.
If you done that previously, try do it again and make sure your script is there. In my case, the first time I open the script editor from the Google Form, it doesn't bound the script. So when I did it the second time, it opens a new script editor with blank template. After I copied my script to the new one, it works perfectly.

Catch response from coded google form [duplicate]

I'm trying to run a script that is connected to one form (A) when a different form (B) is submitted. I have a series of different forms that are similar and needs to run the same script, so instead of copying the code to each script I wonder if this is possible.
I successfully made an installable trigger function in A, pointing at B. I have granted permission when prompted.
When i post B, the script in A fires, and I get this in the log:
Exception: No response with ID 2_ABaOnudSFDkNQOL2Xn4fNOmT95GrTotEW8LSjxfI5qf6qceDN5hD5CHKqNT5D4G_DdONWq0 exists for this form.
at onFormAnswerSubmit(Kod:40:20)
The line (Kod:40:20) that halts is the line that fetches the posted data:
var items = e.response.getItemResponses();
Is this supposed to work or is it impossible to pass posted data from one form to a script in a different form?
Or is there something more I can do in the trigger? Like forcing a pass on of e. or something?
Here is the trigger I created:
/**
* Creates a trigger for when a different form is posted that runs a function in this script (run once)
*/
function createOtherFormTrigger() {
var formID = FormApp.openById("XXXXX"); // form B
ScriptApp.newTrigger('onFormAnswerSubmit') // a function in this script, in form A
.forForm(formID)
.onFormSubmit()
.create();
}
You need to change the logic a bit:
The function fired on trigger should be contained in the same script like the trigger.
Sample code to create a formSubmit trigger for form B:
//run this once
function createOtherFormTrigger() {
var formB = FormApp.openById("XXX");
ScriptApp.newTrigger('onFormAnswerSubmit') // a function in this script, in form B
.forForm(formB) //the active form is Form B
.onFormSubmit()
.create();
}
function onFormAnswerSubmit(e){
var formB = e.source;
var items = e.response.getItemResponses(); //items of the latest form response of form B
var formA = FormApp.openById("XXXX"); // Form A
...
// do what you need to do with form A
}
The code above will create trigger that fires when a form response for form B is being submitted. Thereby it is not important either the script is bound to form A, form B or is standalone. Actually, it might make mosst sense to implement those functions in a standalone script, to make sure that they don't interfer with other form submit triggers you might have in a form-bound script.
I had the same issue. Anywhere where I put e.response I get the same error. It looks that the only workaround is to use a stand alone script instead of a bounded script.
I just understand the problem.
So if you want to catch the response from the form submission, you need to bound your script to the form. To do that, go to your form edit view, then click the three dots, then open script editor.
If you done that previously, try do it again and make sure your script is there. In my case, the first time I open the script editor from the Google Form, it doesn't bound the script. So when I did it the second time, it opens a new script editor with blank template. After I copied my script to the new one, it works perfectly.

onEdit() function does not triggered when change was made by automatic script

my onEdit() function calling to other function when there is a change in the sheet.
if the user makes the change all works fine.
but if the change was made by google-form (the form fill some cells with the answers it gets) onEdit() does not trigger.
do I miss something?
Yes, you forgot to read the documentation for the simple triggers:
onOpen(e) runs when a user opens a spreadsheet, document, or form that he or she has permission to edit.
onEdit(e) runs when a user changes a value in a spreadsheet.
onInstall(e) runs when a user installs an add-on.
doGet(e) runs when a user visits a web app or a program sends an HTTP GET request to a web app.
doPost(e) runs when a program sends an HTTP POST request to a web app.
and installed triggers:
Even though installable triggers offer more flexibility than simple triggers, they are still subject to several restrictions:
They do not run if a file is opened in read-only (view or comment) mode.
Script executions and API requests do not cause triggers to run. For example, calling FormResponse.submit() to submit a new form response does not cause the form's submit trigger to run.
Installable triggers always run under the account of the person who created them. For example, if you create an installable open trigger, it will run when your colleague opens the document (if your colleague has edit access), but it will run as your account. This means that if you create a trigger to send an email when a document is opened, the email will always be sent from your account, not necessarily the account that opened the document. However, you could create an installable trigger for each account, which would result in one email sent from each account.
A given account cannot see triggers installed from a second account, even though the first account can still activate those triggers.
Consider what would happen if your onEdit(e) was activated by programmatic changes, such as if your onEdit function alters the spreadsheet values...
In your situation, where you want form submission to activate your on edit function, You will need to install a form submission trigger (there is no simple trigger for form submissions).
An example function to receive your form submission trigger:
function giveMeAnInstalledFormSubmitTrigger(formSubmitEventObject) {
if(!formSubmitEventObject) throw new Error("You called this from the Script Editor");
var newEventObject = /* do something with the formSubmitEventObject */;
// Call the on edit function explicitly
onEdit(newEventObject);
}
You can read more about the event objects that triggered functions receive in the Apps Script documentation: https://developers.google.com/apps-script/guides/triggers/events
onEdit() will not be triggered by another script editing a sheet or by a form submission.
You can use onFormSubmit(e) instead depending on what your function does it would be a good idea to use the e parameter of the trigger.
https://developers.google.com/apps-script/guides/triggers/events#form-submit
What i have done is that i created an extra sheet with a cell that is the same where the primarecell is(the cell that changes). Leave it for now. I open the scriptapp and write down the code(the code that should happen if the cell changes). Then i wrte down "if" and take the two value i both cells and make an trigger that goes on every minute. With that said, if The cells are the same the "if" is looping on "true". But if something change on the primary cell, it will be "false" and you use "else". Under"else" you should have what ever function you want when soemthing change in that cell. + You must have a funtion where you insert the new value form the primarycell to the "check cell" if u want this too function as loop. Otherwise the "if" code will loop "false" every minute becuse the both cells are not the same.
My english and explaining is not that good:(

onedit why cannot send email?

i've this simple script that should send an email when a cell is changed
function onEdit(e) {
var doc = e.source;
var r = doc.getActiveRange().getValue();
if (r == "Niccolò"){
var a = doc.getActiveRange().setBackground('#ff0000');
var b = GmailApp.sendEmail('name#gmail.com', 'subject', 'body');
}
}
This function change also cell colour.
THe problem is that the cell colour works, so it's change while doesn't send any email.
It looks so simple i don't understand why doesn't works!
Simple triggers like onEdit(), onOpen() or onFormSubmit() have a limited set of possible actions because they run without authorization , see the documentation for further details.
So this behavior you describe is normal.
You should use an installable trigger instead as explained in the same doc page.
here is an summary of the documentation :
These simple triggers run in response to actions in Google Spreadsheets, and they run as the active user. For example, if Bob opens the Spreadsheet, then the onOpen function runs as Bob, irrespective of who added the script to the Spreadsheet. For this reason, the simple triggers are restricted in what they are permitted to do:
They cannot execute when the Spreadsheet is opened in read-only mode.
They cannot determine the current user.
They cannot access any services that require authentication as that user. For example, the Google Translate service is anonymous and can be accessed by the simple triggers. Google Calendar, Gmail, and Sites are not anonymous and the simple triggers cannot access those services.
They can only modify the current Spreadsheet. Access to other Spreadsheets is forbidden.
For more information on event permissions, see Executing from a Container-Specific Trigger.