function onOpen() is not running - google-apps-script

My function includes adding a menu and toast to the document. I have verified that the trigger (onOpen) is set as well. It only works when a user goes into Tools, Script Manager, Run. We have too many users with too many backgrounds to expect then to know how to do this. Why isn't it working? (Using Chrome)
function onOpen()
{
var menus = [{name: "Advance in Workflow", functionName:"sendEmail"}];
SpreadsheetApp.getActiveSpreadsheet().addMenu("Auto Advance FG Workflow", menus);
//sheet.toast(Notify/Remind users);
sheet.toast("While you are here we kindly ask that you do not add, modify or remove any columns.","Welcome - " + username,8);
}
Thanks,

I was having the same issue.
I realized, sometimes Google create some kind of cache of the scripts (I'm used to have a "test" script and I usually alter it's content, and, sometimes, the script runs as if I didn't).
So, what I did that solved the onOpen() not working was changing the function name and ading a trigger manually.
Go to "Resources -> Current script's triggers…"
Choose the function to run on open
It worked like a charm here!
Updated Location Information:
or
Then

This is an old post but I just had this problem and find out why it was not working correctly in my case:
I had, at the top of my script file a variable that required some authorisations and that prevented the script to correctly run. I saw that OP called var username = Session.getActiveUser().getUsername(); (that requires authorisations, and it's may be the cause).
eg:
this code won't work:
function onOpen(){
SpreadsheetApp.getUi()
.createMenu("Exportation")
.addItem("Lancer l'exportation", "exportationMenu")
.addToUi();
}
var stConsCons= SpreadsheetApp.openById(sgcid).getSheetByName("Consultant");
but this one will work:
function onOpen(){
SpreadsheetApp.getUi()
.createMenu("Exportation")
.addItem("Lancer l'exportation", "exportationMenu")
.addToUi();
}
function whatever(){
var stConsCons= SpreadsheetApp.openById(sgcid).getSheetByName("Consultant");
...}

It turns out that you need to add the onOpen(e) function to Triggers!

In my case, onOpen wasn't working because I had a variable, outside of a function, opening a sheet with SpreadsheetApp.openById() rather than SpreadsheetApp.getActiveSpreadsheet(). I guess onOpen doesn't work with openById() even if the sheet you are opening is bound to the script. onOpen() won't work with this kind of a variable outside of a function:
var sheet = SpreadsheetApp.openById("1b_PQD...").getSheetByName("demos")
If your script is bound to the sheet, you can solve this problem by using the getActiveSpreadsheet() function. Otherwise, you can solve it by putting your openById() call into a function.

In my case there was a reference error, that while did not stop the script entirely, it did stop the menu from appearing.
I was only able to detect that error after I run a debug on the script.

It looks like the problem may be that "sheet" isn't defined, which is why the toast is failing.

I know this is a really old question, but for any one finding this now, I may have a solution. The onOpen function often runs with the authorization mode none instead of limited when being used as an event trigger. This may cause errors in things that are related to the specific file or user data. For example:
function onOpen(e) {
SpreadsheetApp.getActivePresentation(); //Will error out if permissions are not set to limited.
SpreadsheetApp.getUi(); //This will always run even if the AuthMode is set to NONE
}
Additionally it is worth noting that if you have any variable used or initialized before onOpen(e), basically any global variables that access sensitive info fail if the AuthMode is set to NONE.
var ss = SpreadsheetApp.getActivePresentation(); //bad
var ss;
...
function init() {
ss = SpreadsheetApp.getActivePresentation(); //good because now that the function is already run we should have full permissions
}

Simple triggers silently fail if they lack permission. I ran into this with an onOpen() in a script that initialized File objects of non-bound files. I moved all File object instantiation to menu functions that do have permission.
In other words, this will not work
function onOpen(e) {
...
let file = DriveApp.getFileById(nonBoundFileId);
...
}
but this will work
function menuFunction() {
...
let file = DriveApp.getFileById(nonBoundFileId);
...
}
because menuFunction can be given permission(s) that simple triggers lack.

Related

TypeError: Cannot read property 'getBody' of null

I'm trying to teach myself to use Google Apps Script, but somehow every function I try returns this error immediately. And since I'm a huge beginner, I don't know what I'm doing wrong.
Here's a simple example of a code I tried to run:
function myFunction(){
//application
//file
var ad = DocumentApp.getActiveDocument();
var docBody = ad.getBody () ;
var paragraphs = docBody.getParagraphs();
//paragraphs[0]. setText ("MY NEW TEXT"):
//var attr = paragraphs[0].getAttributes() ;
//Logger.log(attr);
paragraphs[0].setAttributes({FONT_SIZE:40});
}
Yet no matter what I'm running really, I get this:
TypeError: Cannot read property 'getBody' of null
myFunction # Code.gs:5
What am I doing wrong?
I have an open Google Doc, I've allowed permissions to run the script project. What else should I try? Thanks.
In order to get getActiveDocument() working you need to use it in a script that is container-bound:
Create a new Google Document
Go to Extensions > Apps Script
Run your function inside of it.
If your script is not container-bound, you need to use the openById(id) or openByUrl(url) methods, in order to retrieve a Document
Adblock software was preventing the running somehow. Disabled it and runs fine now. Disregard!

Looking for an onEdit script that can be used to change the color of a google sheets cell when it is edited?

I am using google sheets to monitor a project that includes multiple users. I would like to use an onEdit command to change a cell's color to yellow when the content is edited. Below is the code that I am working with. However, I am unable to get it to function. Coding is still new to me, so any advice would be greatly appreciated.
function onEdit1(e)
{
var range=e.range;
var column=range.getColumn();
if(column>3 && column<27)
{
range.setBackground('#ffff00')'
}
}
function onEdit(e){
if(e.range.getSheet().getName()!="Sheet1")return;
if(e.range.columnStart>3 && e.range.columnStart<27) {
e.range.setBackground('#ffff00');
}
}
I also added a line to limit it to only one sheet. You may wish to change the name of that sheet or even remove it entirely if you want it to run on your entire spreadsheet.
A lot of new programmers try to run these onEdit(e) functions from the script editor. Unfortunately, that doesn't work because the e parameter is expecting to be populated by the event trigger. Without the event object you'll normally get an error like Cannot read property range from undefined because e has not been populated by the event trigger.
I test them by making sure I'm editing the correct sheet and correct range and I use the e.source.toast() function to provide me with feed back sort of like the console.log() does.
If you want to learn more about the event object then try adding a Logger.log(JSON.stringify(e)); to the first line after the function declaration. And then get it to run by editing the appropriate sheet in the appropriate way and go to view log to see the results.

Google Sheets - Script function could not be found

I am working to link an image in my Google Sheet document to a specific cell in another tab. I'm doing this by building a simple function that will do this. However, when I assign the function and then click on the image, I then get the error "Script function "test" could not be found". When I run the function in the script manager interface, it works fine. It's when I try to actually use it in the sheet with the image.
Function Script:
function test()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("TX Marketing Data");
sheet.setActiveRange(sheet.getRange("A91"));
};
Steps to recreate:
1) Create image
2) Go to image, right click, go to drop down and select "Assign Script"
3) Enter "test" as the assign script
Remove ";" at the end of your function (after }).
Had a similar problem and just solved it.
When assigning a script function to a button make sure to call the specific function name(i.e. "getWeatherData") and not the App Script name (i.e. "WeatherAPI").
Another thing that can happen is that you have a library that has the same name as the function. For example you have imported a library that to refer to "test" in your code. If you name your function
function test(){
your code
}
Then you will get the same error that you got.
Try reloading the page.
Sounds like a simple 'turn it off and on again' fix but after having the same issue and trying to save a new version, renaming the function, creating new function etc. a page reload was all it took!
I had exactly the same problem. Eventually I found the problem when I looked at the script Function name, which should be Function followed by the name you gave the script when it was created. when creating file names sometimes you are not able to use special characters which is what I had done. Once I gave it a name that had allowable characters there was no problem. In programming when you call a function that does not match the name given to the function or procedure you will end up getting the error function not found.
I had the exact same issue, when I used submitdata , after I changed it to submitData it said it submitdata was deleted. so i put it back to original form and bam!! fixed.
Same issue, but much dumber reason for me.
So, here is my answer: Make sure to hit the "Save" button in Apps Script.
I was so used to all the other google apps automatically saving/syncing I didn't realize that I actually had to hit "Save" on the scripts. I caught it when I noticed the function I was trying to run wasn't appearing in the list of functions to run in Apps Script. Once it hit save, the name of the function appeared in the list AND clicking my button ran it successfully from the sheet.
You should call your function name, not the script itself. If your function is called myFunction() you should write myFunction. And be careful to rename your function to something that isn't already in your library
Ran into the same issue but solved it by renaming it with a prefix, executing it in Sheets and then renaming it back without the prefix.
function calculateSomething() {
return 10;
}
To
function prefixCalculateSomething() {
return 10;
}
Update the Sheet with the new name, it should work now.
Now rename it back.
function calculateSomething() {
return 10;
}
Update the Sheet with the original name, and it should still work.
Maybe a refresh would've worked as well but that's not how I solved it.
I found that I had renamed my Macro, removed spaces, and added Uppercase, but the name in the script function statement didn't match what I could swear I had set in
"Extensions->Macros->Manage Macros".
When I changed the syntax of the image to match the function statement, including case, it worked fine.
(I don't know if spaces work in the name, I originally had them, but remembered that I've had trouble with them in Excel. I removed them at the same time as doing other changes, so I didn't confirm if it was an issue.)

Google Spreadsheet - Custom menu won't load because onOpen won't fire

I'm doing everything as prescribed in the 'Defining Spreadsheet Menus' tutorial. The menu is modified using the onOpen event handler.
I have made this 'Text to Columns' script available publicly in the 'Script Gallery' but I'm concerned that users who download may be confused when it takes a long time for the custom menu to pop up.
Getting the script to load the first time is proving to be a pain. Much of the time the onOpen trigger is missed altogether. It appears that the trigger isn't being set correctly because manually resetting the onOpen trigger will fix it.
For personal use I'd consider this a minor annoyance but for a shared script it becomes a support issue.
Note: Every subsequent load consistently takes about 7 seconds to appear which is OK but far from ideal.
Here's the onOpen handler:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({ name:"Text to columns", functionName:"textToColumns" });
menuEntries.push({ name:"Text to columns (custom separator)", functionName:"textToColumnsCustom" });
menuEntries.push(null);
menuEntries.push({ name:"Columns to Text", functionName:"columnsToText" });
menuEntries.push({ name:"Columns to Text (custom separator)", functionName:"columnsToTextCustom" });
ss.addMenu("Advanced", menuEntries);
}
Note: This was tested on a new (ie empty) spreadsheet with only one user.
i'm not sure but the user have to log in i guess, if not, i've got this problem once and solved it with making tow or more triggers all of them are on open and the same function,however try to get internet speed more than 30KB/s to make sure that the problem is from the code , not from your devices

Creating a programmatic trigger fails silently

Can anybody see anything wrong in this code
// make new ssheet
var payablesNewDoc=SpreadsheetApp.getActiveSpreadsheet().copy(newName); // NB undocumented function
// Create onEdit trigger for the new Spreadsheet
var onEditTrigger = ScriptApp.newTrigger("onChange")
.forSpreadsheet(payablesNewDoc)
.onEdit()
.create();
Logger.log(onEditTrigger.getHandlerFunction()); // logs "onChange"
Logger.log(onEditTrigger.getEventType()); // logs "ON_EDIT"
It runs without error, and the two log messages seem to indicate that the trigger was created. However when I open the new spreadsheet and make an edit, nothing is fired and the script editor doesn't show any declared triggers.
because it seems in this instance you are making a copy of the host Sheet and script, the onEdit can be added as a simple trigger within the template script, i.e. a function so defined: function onEdit() { // do stuff }.
This function will be copied along with the Spreadsheet itself.
function onEdit() {
// This function being present will automatically add an onEdit trigger
// It can act as a parent for calling any other functions
// e.g. onChange() as per your example
}
One improvement you could make if you are likely to have many copies of the same script floating about you can call a handler function hosted in a library elsewhere to keep your triggered code in one place. If you attach the external script as a Library with development mode turned on, this Library will also be attached to any copies you make to the original Spreadsheet. This will allow you amend the triggered code without having to open all the copies
Make a standalone GS script with a handler function that will replicate the functions you originally wished to trigger, you will need to pass the active sheet by Id thusly:
function editFunction(event) {
try {
var range = event.source.getActiveSheet().getActiveSelection();
return "cells " + range.getA1Notation() + \
" changed to " + range.getValues().toString() + \
" in \"" + event.source.getName() + \
"\" by " + Session.getEffectiveUser();
} catch (err) {
return err;
}
}
then in your template Spreadsheet add the external script as a library (e.g. named EditLibrary).
within your simple onEdit() function simply call the Library function instead of anything inline; passing event details as a parameter.
function onEdit() {
Browser.msgBox(EditLibrary.editFunction(eventObject));
}
that should do what you need with no need to use the triggerBuilder and allowing you amend your code later.
On this thread Is there any way to install an "on edit trigger" in another google docs spreadsheet?
I read
"While it is possible to add an onEdit trigger for another spreadsheet, the trigger will always belong to the script that created it, and can only run functions within the script that created it. – Eric Koleda Jun 30 at 0:05"
Perhaps this is the explanation?