How to create a Message-Box in Google Apps Script - google-apps-script

I am creating an new Google Apps Script about GDrive/New/More/Google Apps Script.
The script is running perfect and on the end my intention is to send a Info on the Desk.
When I am using this line:
Browser.msgBox("TEST");
I get the error back:
Exception: Cannot call Browser.msgBox() from this context; have you tried Logger.log() instead?
Logger.log can't be the solution, because I don't see the result on the desktop, but only in the log files.
Is there another solution or is it possible to get a simply example what I can do?

In this case Browser.msgBox is a method for the Browser class, this class is specifically meant to be used in Spreadsheets as stated in the documentation:
Class Browser
This class provides access to dialog boxes specific to Google Sheets.
The methods in this class are only available for use in the context of a Google Spreadsheet.
If you want a notification you could use either the Browser.msgBox method or the Toast method, either way they both need to be applied in a Spreadsheet in order to work.

Related

Google Apps Script Cannot Find Browser Class

So I began experimenting with Google Apps script (to automate a google slide maker), so I created a test function. This is all the code:
function myFunction() {
Browser.msgBox("Hello World");
}
This gives me an error: Exception: Cannot call Browser.msgBox() from this context; have you tried Logger.log() instead? (line 2, file "Code"). Before I verified and allowed authorization, when I typed Browser. it would give me options. After I authorized, nothing popped up. This means that the authorization is the problem. Does anyone have a fix for this?
Also, google never made me type "continue" during the authorization.
The Browser class is only available for Google Sheets, not Google Slides. See its documentation:
This class provides access to dialog boxes specific to Google Sheets.
The methods in this class are only available for use in the context of a Google Spreadsheet. Please use Google Workspace dialogs instead.

Share a custom google sheet function with another email address without showing the source code

Iv'e written a custom google sheet function using Google Apps Script, and i would like to share it with another spreadsheet user, but i do not want to share the functions source code.
I've converted the Google Apps Script to a project, but now i have no idea how to link the project back to my sheet, so the function will work again.
I also do not want to publish the AddIn to the marketplace.
Test As Addin also doesn't work, the sheet is opened in a new tab, but the cells with the custom function says #NAME?.
What am i missing?
Explanation / issues:
The error #NAME? indicates that you are trying to use a function
that does not exist. As you also mentioned, this function does not
belong to the active spreadsheet but on a different project.
Unfortunately, it is not possible to share a custom function with other spreadsheets directly.
Possible Workarounds:
You can create an add-on.
Another workaround solution would be to create a library. That is a great alternative and the documentation is quite straightforward.
Related:
Creating add ons in Google Apps Script
How to call library function as custom function from spreadsheet formula?

Centralized script for multiple spreadsheets

I have created a Notification script and would like to use it for multiple spreadsheets (produced by Forms). I would like to have a centralized script and referencing it on my multiple spreadsheets in order to simplify maintenance.
I have tried to use the SpreadsheetApp.openById() like below but looks like this feature has been disabled for security reasons and is not supported anymore.
function append()
{
SpreadsheetApp.openById("1xdePF..........................");
}
Any idea on how to use the same script for multiple spreadsheets?
The documentation specifies that openById opens the spreadsheet with the given ID.
You cannot use this method to open a script.
To open an Apps Script, go to https://script.google.com/home/my and clock on the script of your choice.
For bound scripts, you open the document to which the script is bound and go to Tools->Script Editor
Preface
This answer is supplementary to ziganotschka's, since you indeed cannot access the script bound to a document by opening said document with openById(). The answer, instead, covers other issues you had and suggests additional ways to solve your task.
Problem
When trying to use openById() you receive an error message of the following structure:
Exception: Document [doc id here] is missing (perhaps it was deleted, or maybe you don't have read access?)
You mentioned in comments that the id is 58 chars (I bit it is 57) and obtained from "properties", which explains the error - there is no spreadsheet with such an id, because file id and script id you extracted are not the same thing. If you ever need to extract current id programmatically (here it is assumed to be called from a script bound to spreadsheet, but other services have similar methods), you can call getActiveSpreadsheet() -> getId().
Solutions
You stated that you need a maintenance script, so how about creating a standalone script project that is deployed in a way any document can access:
As a library
Any script that has a saved version can be a library that can be used by other scripts by adding its id to the list accessible from Resources->Libraries menu.
As a Web App
Any script that has a doGet, doPost function (or both) can be deployed as a Web App, essentially exposing it to the net. Since you said that the spreadsheets are "produced" by Forms, and you created a "notification" script, I assume you are interested in a FormSubmit event. When you deploy as a Web App, you get a url (don't forget to choose an appropriate permission).
After that, it is only a matter of making sure that:
each Form has an installable onFormSubmit trigger (you can instlall it via [please see refs for docs] ScriptApp.newTrigger('callback name').forForm('form ref').onFormSubmit()).
The callback for the trigger calls the Web App url via UrlFetchApp.fetch() with necessary data (like spreadsheet id or any other info) as query (if using doGet) or request body (if using doPost).
The data you need will be available in the event object constructed on hit to doGet or doPost [note to avoid common misconception: you can't debug event objects in the editor, it can only be done live].
Reference
getActiveSpreadsheet() docs
getId() docs
getFileById() docs
Standalone scripts guide
Bound scripts guide
Libraries guide
Form submit event reference
new Trigger() docs
UrlFetchApp.fetch() docs
doGet / doPost event object docs

Can I make custom function on google spreadsheet without Google Apps Script?

I'm using google spreadsheet with Google Apps Script.
but it gives me error message too easily. like this
Error
Script invoked too many times per second for this Google user account. (line 0).
Is there any way to avoid the error? (except the way reduce function call)
or alternative Spreadsheet program that support Javascript function define?
As noted in the documentation you can work around this by ensuring that your function supports ranges, and the function on a range. See also the section on Optimization on the Custom Functions in Google Sheets page.
To create a custom function you should use Google Apps Script, it's the only way. Regarding the way to avoid the error, there are several things that could be done but to be certain about what is required in your case you should add more details.

You do not have permission to call openById

Problem: When I run the script, Google tells me,
You do not have permission to call openById
I had copied a script from another one of my Google spreadsheets and changed the target_ssKey variable's cell reference and created properly-sized Named Ranges in both the Source and Target spreadsheets.
Google Apps Script documentation says nothing about reasons why it might not be working:
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#openById%28String%29
Another Google Apps Script documentation says that it should work for me because I invoke it from a custom menu:
https://developers.google.com/apps-script/guides/sheets/functions#using_apps_script_services
The second link above says:
If your custom function throws the error message You do not have
permission to call X service., the service requires user authorization
and thus cannot be used in a custom function.
To use a service other than those listed above, create a custom menu
that runs an Apps Script function instead of writing a custom
function. A function that is triggered from a menu will ask the user
for authorization if necessary and can consequently use all Apps
Script services.
I tried putting the function into a "Custom Functions" project and then into an "Add-on" project, but still got the same error message.
Any ideas on what I am doing wrong and how to make this work?
Here is my exact code:
function exportData_SStoSS() {
// Get the source data.
var source_ss = SpreadsheetApp.getActiveSpreadsheet();
var data = source_ss.getRangeByName("exportData").getValues();
// Identify the target.
var controls_sh = source_ss.getSheetByName("Controls");
var target_ssKey = controls_sh.getRange('C2').getValue();
var target_ss = SpreadsheetApp.openById(target_ssKey);
// Paste the data to the target.
target_ss.getRangeByName("importData").setValues(data);
};
I thought that I would throw in a similar issue that I had which brought me to this question, where I received the error You don't have permission to call by openById.
In my case I was trying to call functions from translate.gs which I copied from this example:
https://developers.google.com/apps-script/quickstart/docs
Note that at the top of translate.gs
/**
* #OnlyCurrentDoc
*
* The above comment directs Apps Script to limit the scope of file
* access for this add-on. It specifies that this add-on will only
* attempt to read or modify the files in which the add-on is used,
* and not all of the user's files. The authorization request message
* presented to users will reflect this limited scope.
*/
The culprit here is the #OnlyCurrentDoc comment. See here for reference:
https://developers.google.com/apps-script/guides/services/authorization
Removing #OnlyCurrentDoc fixed this issue for me
I could resolved this issue with this autorization guide of google developers.
https://developers.google.com/apps-script/concepts/scopes#setting_explicit_scopes
This entry It's necesary in json file.
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets"
],
I found this official note which I believe clears up what caused the issue.
If your function is a custom function, that is one which can be used like a regular spreadsheet function in the sheet itself, then it has limited access to things and cannot open other spreadsheets.
The same script can however open other spreadsheets from a menu button or similar.
Link: Documentation at developers.google.com
The method openById can be called from a "Blank Project" but not a "Custom Functions in Sheets" nor a "Google Sheets Add-on" project.
I thought a "Blank Project" would create a project that was not connected to my spreadsheet, but I was wrong. The Blank Project is connected to my spreadsheet. The other types of projects that I tried to use seem to be limited-scope versions of script projects, not able to carry out some GAS methods.
Had this same issue and came to share my solution. In my case I had two spreadsheets, call them A and B. Both used scripts bound to each respective spreadsheet. Spreadsheet B was able to write data to a tab of spreadsheet A. But Spreadsheet A kept getting the "You do not have permission to call openById" error when trying to read from spreadsheet B. I then tried adding it as a custom menu item but still the same issue.
The solution in my case turned out to be really simple. I created a new unbound script in script.google.com that calls both spreadsheets using openById. The first time running put a smile on my face as it asked for authorization. Thereafter smooth sailing.