I'm having trouble with the autocomplete feature in Google App Script.
Built-in methods like SpreadsheetApp. will provide an autocomplete menu with methods to choose from.
However, if I create my own child object, autocomplete works for a little while, and then it just stops working.
for example:
var skywardRoster = SpreadsheetApp.getActiveSheet();
skywardRoster. will produce method options for a while, and then it stops.
However, the code still functions, and methods work if I type them out manually, so I know the declarations must be right. The menu simply won't appear, and it's just very inconvenient to have to look up each method individually as I go.
I have tried: breaking the variable and retyping that line; copy and pasting the code back into the editor; using different browsers; copying the gs file itself and working within the copy; and signing out completely and signing back in. Nothing seems to get it back to work.
I'm really new to coding, and I'm not sure what can be causing this.
Does anyone know how to fix this issue?
You might want to check Built-in Google Services:Using autocomplete:
The script editor provides a "content assist" feature, more commonly called "autocomplete," which reveals the global objects as well as methods and enums that are valid in the script's current context. To show autocomplete suggestions, select the menu item Edit > Content assist or press Ctrl+Space. Autocomplete suggestions also appear automatically whenever you type a period after a global object, enum, or method call that returns an Apps Script class. For example:
If you click on a blank line in the script editor and activate autocomplete, you will see a list of the global objects.
If you type the full name of a global object or select one from autocomplete, then type . (a period), you will see all methods and enums for that class.
If you type a few characters and activate autocomplete, you will see all valid suggestions that begin with those characters.
Since this was the first result on google for a non-working google script autocompletion, I will post my solution here as it maybe helps someone in the future.
The autocompletion stopped working for me when I assigned a value to a variable for a second time.
Example:
var cell = tableRow.appendTableCell();
...
cell = tableRow.appendTableCell();
So maybe create a new variable for the second assignment just during the implementation so that autocompletion works correctly. When you are done with the implementation you can replace it with the original variable.
Example:
var cell = tableRow.appendTableCell();
...
var replaceMeCell = tableRow.appendTableCell(); // new variable during the implementation
And when the implementation is done:
var cell = tableRow.appendTableCell();
...
cell = tableRow.appendTableCell(); // replace the newly created variable with the original one when you are done
Hope this helps!
I was looking for a way how to improve Google Apps Script development experience. Sometimes autocomplete misses context. For example for Google Spreadsheet trigger event parameters. I solved the problem by using clasp and #ts-check.
clasp allows to edit sources in VS Code on local machine. It can pull and push Google Apps Script code. Here is an article how to try it.
When you move to VS Code and setup environment you can add //#ts-check in the beginning of the JavaScript file to help autocomplete with the special instructions. Here is the instructions set.
My trigger example looks like this (notice autocompletion works only in VS Code, Google Apps Script cloud editor doesn't understand #ts-check instruction):
//#ts-check
/**
* #param {GoogleAppsScript.Events.SheetsOnEdit} e
*/
function onEditTrigger(e) {
var spreadsheet = e.source;
var activeSheet = spreadsheet.getActiveSheet();
Logger.log(e.value);
}
I agree, Google Script's autocomplete feature is pretty poor comparing with most of other implementations. However the lack is uderstandable in most cases and sometimes the function can be preserved.
Loosing context
The autocomplete is limited to Google objects (Spreasheets, Files, etc.). When working with them you get autocomplete hints, unless you pass such object instance to function as an argument. The context is lost then and the editor will not give you suggestions inside the called function. That is because js doesn't have type control.
You can pass an id into the function instead of the object (not File instance but fileId) and get the instance inside of the function but in most cases such operation will slow the script.
Better solution by Cameron Roberts
Cameron Roberts came with something what could be Goole's intence or a kind of hack, don't know. At the beginning of a function assign an proper object instance to parameter wariable and comment it to block:
function logFileChange(sheet, fileId){
/*
sheet = SpreadsheetApp.getActiveSheet();
*/
sheet.appendRow([fileId]); // auto completion works here
}
Auto completion preserved
Related
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.)
I have a few Simple Custom Functions that I use all the time. I have recently run into a spreadsheet that I desperately need to use them in, but when I try to use even the most basic custom functions, I get "#NAME?" with a hover text of "unknown function".
Even deleting all other code, and trying just this simple function, doesn't seem to work:
function double(d) {
return 2*d;
}
When I duplicate the spreadsheet, the code that comes with it DOES work.
A few Notes:
This is a Google Apps for Enterprise account.
I was originally not the owner on this spreadsheet, but have since become the owner, thinking that this might be the cause.
The spreadsheet originally had protected regions, which have since been removed, thinking that this might be the cause.
This spreadsheet is shared with hundreds of people, so I really want to find the root cause and fix it.
Any thoughts?
Way too late for the OP, but in case this helps someone else:
I had a similar issue where my spreadsheet suddenly stopped recognising custom functions that have been working for months. No code changes have been made recently and the spreadsheet hadn't even been edited since it last worked. When I went to Tools > Script editor it still showed the code with the custom functions.
Reloading the page and closing and reopening didn't fix it. I added a simple parameterless wrapper function to call the custom function with some appropriate arguments.
I then ran this wrapper function in the debugger with a breakpoint in the original custom function. When it hit this, I switched back to the spreadsheet and it could magically see the custom functions again.
If you already published as Add-on, then you need to do reactivate the addon for copied sheet with the following steps:
Click the menu Add-ons / YOUR-ADD-ON-NAME / Help / View in store,
click Manage and in the dropdown menu uncheck then check the 'Use in this document' again for the addon to be loaded to the current sheet.
I can not explain the exact cause, but here is a SOLUTION:
copy the expression written in the cell
delete the content of the cell
re-enter the expression in the cell!
Again, late in the thread, but it was the only thread I found on this --
My function had been running well, too and suddenly returned Unknown Function.
I found that the signature had changed - initially, I had a few parameters I was sending in and the cell returning the error still had parameters in the function call. The function hadn't used parameters for a long time. I removed the parameters and Voila! Apparently, something changed where it started enforcing call patterns...
When you have custom functions on a sheet - they areBOUND to that sheet. So it does work when you duplicate the sheet itself , but it does not automatically become a global or domain wide custom function.
The only way use it else where without actually publishing it as an add-on is to go to the tools menu, click on script editor and actually copy the code from the script bound to that sheet that it works with, then paste it in the script editor of the sheet you want to use it in.
I faced the same problems. I here document, what worked for me.
To create a new custom function, I did the following:
In spreadsheet: Menu -> Tools -> Script Editor
Wrote the function in Script Editor
In spreadsheet: Menu -> Tools -> Import -> Clicked "Add Function" next to the custom function name.
In spreadsheet: In a cell, I did =CustomFunctionName()
This worked.
Now, when I wanted to reuse the same in another spreadsheet, there are 2 ways to do that.
Make Copy of the sheet in which the custom function is written.
Make library of custom functions and reuse them in other sheets, by writing custom functions specific for a particular sheet.
#1 Make Copy of the sheet in which the custom function is written.
In this way, the whole custom function code gets duplicated. So, if any changes needs to be done in the custom function, the change must be done in all the copied files.
Also, once the sheet is copied, the custom function does not simply works. I had to delete the cells & reenter the function names again, to get them working.
#2 Make library of custom functions and reuse them in other sheets, by writing custom functions specific for a particular sheet.
This is better, because, the core logic will stay in one place. Only wrapper functions will be written for each sheet, in which the custom functions are used.
To create a library:
Write the function in Script Editor
Click on "Deploy -> New Deployment"
"Select Type -> Library"
Provide a description, if you want to and click "Deploy" & "Done"
Click on the "Project Settings" on the left menu & copy the "Script Id"(to use the library)
To use a library:
Goto the spreadsheet where you want the library to be used.
Menu -> Tools -> Script Editor
In Script Editor: Click + button next to the Library section on the left.
Enter the "Script Id" & Click on "Look Up".
You will see the script details. Then click on the "Add" button.
Remember the "Identifier" field value. Using that, the functions of the library can be accessed.
Now, in the Script Editor, you can call the library functions with the identifier name. See examples below.
Library Code:
function SheetName() {
return SpreadsheetApp.getActiveSpreadsheet().getName();
}
function SayHello(name) {
return 'Hello ${name}';
}
Let's say, while including this library into a spreadsheet, I entered the identifier as utility. So, in the script editor, I would write like this:
function SheetName() {
return utility.SheetName();
}
How to update a library and use the updated code in spreadsheets?
To update a library:
Make the changes in the library project.
Click on "Deploy -> Manage Deployments".
Select the correct deployment from the left side.
Click on the edit button(on top left).
Select "New Version" in the "Version" input.
Click "Deploy" & make note of the new version number displayed.
To use the updated library:
Goto the spreadsheet in which the library is already being used & open the Script Editor in there.
If the Script Editor of that sheet is already open, reload the page once.
Click on the library name in the Library section(on the left).
Select the latest version number on the Version input & click "Save".
Now, you can call the new functions in the same way you did previously & the existing functions will work in the new way(if there are any changes to the existing functions).
If "copy expression -> delete cell contents -> exit cell -> re-enter expression" fixes your problem, then the easiest way to implement it en masse is to select all faulty cells, hit backspace to delete their contents, and then undo the deletion.
Doing so will force reevaluation of affected cells which bypasses the cache.
I faced exactly the same problem ! My code worked well and was properly linked to the correct spreadsheet. Unfortunately deleting the content of the cell didn't work for me.
Another solution I found is to simply rename the function.
For example:
"myFunction" renamed as "my_Function" and it worked for me ! I guess maybe it's due to an important amount of calls (over 35 000 in my case). Maybe it makes it run into an error or something.
Cheers !
I created a copy of my sheet as a backup and closed up for the night. I came back in the morning with the functions unable to be called. So I did the usual, cut the function from the cell and pasted it right back. This usually fixed things. Not this time.
Tried reopening browser, tried re-logging in. Nothing worked.
Than I simply renamed the function in the Project Editor (appended "call" in front of the function name) and edited the sheet to match. It just worked.
When writing the functions, the comment section was not done properly. Here was what I wrote initially:
/*
A custom function that converts US Dollars to SwissFrancs
#param {number} dollars The total number of dollars
#return {number} swissFrancs The total number of SwissFrancs
#customfunction
*/
Upon inspection of the comments, I found out that I used the comment notation wrongly. I ought to have placed an asterisk just after the opening comment tag /* and on every newline in the comments place an asterisk sign and finally place another asterisk sign before the closing multiline comment tag (*/) like so:
/**
* A custom function that converts US Dollars to SwissFrancs
*
* #param {number} dollars The total number of dollars
* #return {number} swissFrancs The total number of SwissFrancs
*
* #customfunction
**/
One last thing, don't forget to add the #customfunction in the comment section.
As per the documentation by Google, it is important to add the comments before the custom function. Otherwise the function won't appear in the autocomplete popup.
/**
* Multiplies the input value by 2.
*
* #param {number} input The value to multiply.
* #return The input multiplied by 2.
* #customfunction
*/
function DOUBLE(input) {
return input * 2;
}
I've solved as follows
#1. Created 2 instances of the same funcion:
/**
* Multiplies the input value by 2.
*
* #param {number} input The value to multiply.
* #return The input multiplied by 2.
* #customfunction
*/
function DOUBLE(input) {
return input * 2;
}
/**
* Multiplies the input value by 2.
*
* #param {number} input The value to multiply.
* #return The input multiplied by 2.
* #customfunction
*/
function DOUBLE2(input) {
return DOUBLE(input);
}
The second instance returns the result of the first one
#2. Created a function to fix the issue:
function updateFormulas_() {
var f = SpreadsheetApp.getActive();
var r = f.getActiveRange();
var f1 = 'DOUBLE('; // !! Mind "("
var f2 = 'DOUBLE1(';
var finder1 = r.createTextFinder(f1).matchFormulaText(true);
var found1 = finder1.findNext();
if (found1) {
finder1.replaceAllWith(f2);
}
var finder2 = r.createTextFinder(f2).matchFormulaText(true)
var found2 = finder2.findNext();
if (found2) {
finder2.replaceAllWith(f1);
}
}
Note I've added opening parentheses to my functions in replacements in order not to break the original.
#3. Created onOpen Custom menu
function onOpen() {
createMenu_();
}
function createMenu_() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Dispatch menu')
.addItem('Update Formulas', 'updateFormulas_')
.addToUi();
}
Now if error occurs user can select a range with error and fix it manually.
The other option #3 is to create a time trigger to do this.
Another late entry. This error can also come as a signature violation. This can occur if the type of variable being passed into the custom function is different from what is expected. I was "cleaning up" my spreadsheet and re-formatted some of the entries. This caused a not found. Detecting this error is made easy if you enabled the function for prompting. In my case I started typing the function name and it came up (so Google knew it was there), but when it came to execution I got the error.
I am creating some google app scripts for my company to use to generate random tests for employee training. I already have the basic scripts written to grab a list of questions from a google sheet, randomize them, grab the first 10 questions, etc. That all works fine. I decided it might be better to re-do the whole thing using a UiApp instead of just separate scripts. That is where the problem comes in. I did a simple bare bones UiApp to test with, published it and tried to hit the URL and that's where I encounter this error. I searched for this error and all I could find was some discussion about this being part of google apps premiere(which should have been folded into regular google apps around 2010). I've been staring at this so long I've frustrated myself. It should be something very simple and yet it's refusing to work. I'm assuming I am doing something wrong at a basic level but I've reached the point where my brain refuses to see it.
Here is the basic script I started with:
function doGet(e) {
var app = UiApp.createApplication();
var mainPanel = app.createVerticalPanel().setId('mainPanel');
mainPanel.add(app.createLabel('test'));
return app;
}
I save it, publish it and go to the URL and that's when I get the above error message. I know it's something simple but I've reached the point of frustration and simply can't see it.
Update: to reflect comments
Another possibility for WebApps not updating is not publishing a new version and only checking the exec URL. For instant changes to the code, always check the dev URL. The exec will only change after saving a version in Manage Versions and re-publishing the app.
First Answer:
I think your question title says it all.
UIApp is not defined, but Class is UiApp. JS is case sensitive. I copied and pasted the code exactly as it is in your question and received no errors. I did have to add one line to make the label show up.
function doGet(e) {
var app = UiApp.createApplication();
var mainPanel = app.createVerticalPanel().setId('mainPanel');
mainPanel.add(app.createLabel('test'));
app.add(mainPanel); // <-- I added this line to see the label
return app;
}
SPECIFIC FOR: "NEW" google sheets only.
This is a known issue as highlighted by google in the new sheets.
Issues: If you write complex* custom functions in google-apps-script for google sheets, you will occasionally run into cells which display a red error box around the cell with the text "Loading..."
Google has suggested:
If this occurs, try reloading the page or renaming the function and changing all references to the new name.
However for other developers experiencing this issue (and who are unable to escape the "loading..." error), I've written my findings in the answer below on how to get past this (with limitations) consistently.
*We're treating this question as the canonical answer for Google Sheet's indefinite "Error... Loading data" problem. It's not limited to complex or slow functions.
Important Tip: Create multiple copies of your entire spreadsheet as you experiment. I have had 3 google spreadsheets corrupted and rendered completely in-accessible (stuck in a refresh loop). This has happened when I was experimenting with custom functions so YOU HAVE BEEN WARNED!
You will want to try one or many of the following ways to fix this issue:
As suggested by google, try re-loading the spreadsheet or re-naming the function or changing the parameters in the cell to see if this fixes the issue.
Surround ALL your custom functions in a try-catch block. This will help detect code issues you may not have tested properly. Eg:
try{
//methods
}catch(ex){
return "Exception:"+ex;
}
Revert to the old sheets and test your functions and check for any other type of error such as an infinite loop or invalid data format. If the function does not work in the old sheets, it will not work in the new sheets and it will be more difficult to debug.
Ensure NONE of your parameters refer to, can expect to or will ever contain a number larger than 1 million (1000000). No idea why but using a number larger than a million as any parameter will cause your function to fail to execute. If you have to, ask the input to be reduced in size (maybe divide by 1000 or ask for M instead of mm).
Check for numeric or floating point issues where numbers may exceed a normal set of significant figures. The new sheets seems to be a little glitchy with numbers so if you are expecting very large or very complex numbers, your functions may not work.
Finally, if none of the above work, switch to the old google sheets and continue working.
If you find any other limitations or causes for functions to fail to execute, please write them below for me and other users who are heavy g-sheet users!
I also had the infinite loading issue with the following function.
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope";
if( have >= need ){
retStr = "yep";
}
return retStr;
};
Turns out you shouldn't have a trailing ";". Removing the semicolon solved the problem.
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope";
if( have >= need ){
retStr = "yep";
}
return retStr;
}
This runs as one would expect.
FWIW, I just ran into this and the culprit ended up being a getRange() call that pulled several thousand rows into an array. Periodically it would get hung on the "Loading..." message.
I worked around it by putting that range into the document cache. It's a little kludgy because the cache only stores strings, not arrays, but you can force it back into an array using .split(',') when you need to access the array.
(In my case it's a single array. There's probably a way to do it using a double array, either by sending each row or column into its own cache, or reading the cache value back N items at a time, each N becoming its own array.)
Here's the relevant bit from my code:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("mySheet"); //search the "mySheet" sheet
// is the big list already in the cache?
var cache = CacheService.getDocumentCache();
var cached = cache.get("columnValues");
if (cached != null) {
var columnValues = cached.split(','); // take the cached string and make it an array
} else { // it's not in the cache, so put it there
var column = 1; // the column with your index
var columnValues = sheet.getRange(2, column, sheet.getLastRow()).getValues(); // first row is header
cache.put("columnValues",columnValues,60000); // this forces the array into a string as if you used .join() on it
}
This is definitely a bug in Apps Script -- getRange() shouldn't hang without a timeout or error message. But at least there's a workaround. Here's the bug I opened against it, where I've also put the full code.gs from my sheet.
One cause: Permissions needing authorizing.
As far as {this problem, better phrased the cell result(s) of a custom function displaying the disgustingly-vague message ‘Loading... Error: loading data...’}, indeed in the case where all instances of the same/similar custom function call displaying this error, is that Google Sheets needs permissions to run the script (often additionally: meaning in the past it didn't need these), so instead of {acting appropriately: then prompting the user for these permissions else returning that error}, Sheets instead hangs with this disgustingly vague error.
Additional permissions can be needed from 1 or more:
Google App Scripts has since rewriting their permission structure --how this problem now just happened to me, per my internal note O80U3Z.
Your code or some library it uses made changes to require more access ...but in this case you have a much better chance of guessing the cause of this disgustingly-vague error, so hopefully won't be reading here.
To fix, I explicitly ran my GAS spreadsheet code by both: clicking one of my custom menu functions and, in the ‘script editor’, running one of my custom JS functions notably the ‘onOpen()’ since that is most comprehensive. The first promoted me for indeed new permissions, via popup ‘Authorization RequiredThe application "MM6ZBT(MM6Z83 script)" needs authorization to run.’, though onOpen() also did this in cases of GAS revising its permissions since we used that sheet. Then, as I was still getting this ‘Loading...’ error, I reloaded the web page (so the sheet), and, at least for these cases of this disgustingly vague error, it was gone and the computations worked fine :-)
TL;DR - Try duplicating the sheet tab and delete the old one
I struggled with this issue today, and tried some of the approaches mentioned. For various reasons, renaming the function wasn't possible for me.
It was very clear that if I called a my function like this in cell X25:
=myFunction("a", 1, "b", 2, "c", 3)
The cell would be stuck "Loading...", while just changing a parameter slightly (e.g. converting a number to a string) the cell would evaluate fine.
=myFunction("a", "" & 1, "b", 2, "c", 3)
Just copying the code into another cell (e.g. X24) and executing it there seemed to bypass the problem. As soon as I moved it back to the original parameters or cell, it got stuck "Loading..." again.
So I would assume it's some kind of caching of "Cell ID", function and parameters that go bonkers on Google's side.
My good-enough solution was to simply duplicate the Sheet tab, delete the old one, and finally rename the new one back to the original name. This solved the problem for me.
I also had the "loading data..." error but none of the fixes described here worked for me. It didn't seem to be caused by the issues described here. In my case, I narrowed it down to a specific floating point operation issue (it looks like a real bug in Google Sheets to me), and documented one possible work around at
Google Sheets / Apps "Loading data" error: is there a better workaround?
To summarize (at the request of commenter Steve), if a cell with
= myfunction(B10)
generated a "loading data" error, then for me it could be fixed by wrapping the argument in a "value()" function:
= myfunction(value(B10))
which converts the number in cell B10 (which seemed like a normal number but generated problems somehow) into a normal number that works fine.
I also had the problem that you explained. It seems that it can be caused in more than one way.
I ended up finding that my custom function was displaying that error because it relied on data from an =IMPORTRANGE() call, and that call was failing.
I eventually found that the =IMPORTRANGE() call was failing because I had forgotten to update the URL that it was importing from when I had uploaded a new version of that imported-from sheet. It seems that trying to IMPORTRANGE from a trashed file can cause the infinite "Loading..." error.
Update 2022
It looks like this bug is still happening. I tried ALL the solutions mentioned here but none worked.
What worked was to start with a blank slate. I recreated the file, copy-pasted my data, reapplied my preferred style and format, and lo-and-behold the sheet finally managed to pull the data using my custom functions.
This is a definitely a bug on Google's end - and it's all the more annoying because they removed the "Report a problem" button from the "Help" section.
Nevermind
The newer sheet has stopped working too. This is so annoying ..
The problem is that when a custom function formula cell starts showing Loading..., the custom function does not get called at all. The code in the script project thus does not come into play. Even the simplest custom functions sometimes suffer from the issue.
The problem usually goes away if you clear the formula cell and undo, or slightly edit the custom function's parameters to cause it to get re-evaluated. But that does not solve the issue. Google has been dragging their feet solving the underlying cause for many years.
To help the issue get Google's attention, star issue 233124478 in the issue tracker. Click the star icon ☆ in the top left-hand corner to vote for fixing the issue and get notified of status changes. Please do not post a "me too" or "+1" reply, but just click the star icon. Google prioritizes issues with the most stars.
Add-ons
I had two add-ons, and no function was loading.
I removed them, and all is well!
For me, renaming the custom function solved the problem. For now at least.
Just to add to Azmo 's answer...
I in fact removed all trailing semi-colons from the code:
// check if an item can be checked off
function checkedOff( need, have ) {
var retStr = "nope"
if( have >= need ){
retStr = "yep"
}
return retStr
}
And discovered, that when doing this over a large range you can also max out the acceptable number of calls to the API.
To get around it I added an IF THEN check around my custom script call.
So instead of:
=checkedOff(H10,H11)
Use something like this to check for a populated field before execution:
=if(H17<>"-",checkedOff(H10,H11),0)
My app script pulling data from my MSSQL database displayed just fine on GoogleSheets my laptop browser but then did not display on the Android GS app.
Per this thread it looks like there's a number of issues that could cause this, but #DestinyArchitect's answer above re: Permissions seemed like the simplest fix.
While testing my app script, Sharing was off for this GoogleSheet file.
Once I moved it to my team's folder where we have default Sharing switched on with a few team members, the MSSQL data showed right up on the GoogleSheet in my Android GS app.
Easy fix, this time...
In my case, the cell was stuck with a Loading... message due to "probably" a race condition between functions and formulas resolutions.
This is my custom function:
function ifBlank(value1, value2) {
return !!value1 ? value1 : value2;
}
This is the formula calling it:
=IFBLANK(VLOOKUP($A2,Overrides!$A$2:$E,5,FALSE),VLOOKUP($A2,'_resourceReq'!$A$2:$C,3))
Those VLOOKUP values could be pretty complex and could also take some time to resolve.
Solution: (in my case)
Wrapping the VLOOKUP() into TO_TEXT() or VALUE() for example.
So, changing the formula to =IFBLANK(TO_TEXT(VLOOKUP($A2,Overrides!$A$2:$E,5,FALSE)),TO_TEXT(VLOOKUP($A2,'_resourceReq'!$A$2:$C,3))) worked well.
If that doesn't work maybe try resolving the value from a function into a cell before using it as the argument of your custom function.
In my case, multiple cells using functions experienced this issue, but the simple answer was... wait.
In my case, I was scraping data via importXML functions across multiple rows and
columns. I was thrilled with the results, feeling on top of the world, then "Loading..." started showing its ugly face. For way too long. That's how I wound up here in troubleshooting mode, impatient and upset that Google was doing me wrong.
I tried many of the solutions here, only to find my "Loading..." antagonist acting unpredictably, popping up randomly like whacamoles, nothing to do with the code itself.
So. In my case, it was a matter of waiting it out (towards an hour for some rows, but I had so many cells fetching url data).
My layman's guess is that fetching data like this gets put in their bandwidth pipeline, lesser priority than typing a url into a search bar or other user requests.
In this post, I suggested to use the ScriptDB as an intermediate storage for global data of a Container Extension code. I wrote a sample code for my answer but the sample throws the error: You do not have permission to call query (line X) exception in a ScriptDb.getMyDb().query(...); line. I created the following simpler example demonstrating the problem. The code, both getDBSize and getSource functions, is permitted to use the ScriptDB by running it in the editor. The getDBSize function is executed without any problem by pressing the Run button in the Spreadsheet Script Manager Dialog. The getSource function works everywhere.
I published the Spreadsheet for the example - link. It is impossible to share the code for view, but it is possible to output it in a cell, the cell B3 contains exactly bellow code.
How is possible to permit the Spreadsheet Code to have access to the ScriptDB?
function getDBSize() {
var db = ScriptDb.getMyDb();
var result = db.query({});
var count = result.getSize();
return count;
}
function getSource() {
return this.toSource();
}
The problem is that you're trying to run this function as a spreadsheet custom function, and custom functions are way more limited than all examples on the Container Extension page you linked.
But, from a theoretical point of view, custom functions as well as simple event handlers (e.g. onEdit, onOpen), can not access anything that requires the user account or is associated with the user, only "generic" methods. For example, UrlFetchApp, open the current spreadsheet, or read ScriptProperties.
So, in thesis, querying a ScriptDb should be possible, since it's a generic call and has nothing to do with the active user, it's analogous to ScriptProperties. I don't see a workaround that would actually let you query the db, but you could use ScriptProperties instead. You can easily save and retrieve any object you would save on ScriptDb by using JSON.stringify and .parse. Of course, I'm not comparing ScriptDb capabilites with ScriptProperties, it's just a workaround.
Anyway, this seems like a good candidate for an enhancement request on our issue tracker.