Create a macro in Google Sheets using Google App Script - google-apps-script

I want to programmatically create a macro and call the same from another stand-alone app script project.
One of the approaches I have used is to create the project using the projects.create API and called the function in that project using scripts.run.
The problem with this approach is that I've to manually set the GCP project for the newly created project, as the script and calling application must share the same GCP project as mentioned here.
I couldn't find any resource to perform it programmatically.
Basically, I want to execute the App script code provided by the user dynamically from my existing Google Sheets add-on.
Any suggestion or help would be great.
Thanks.

Not sure I understand correctly, but lets assume you want to do the following:
Create a Function (your Macro) in a Apps Script Project
Use the Function in the above Project from multiple Google Spreadsheets
In that case you can do multiple things, my suggestions would be
Create a Apps Script Project
Enter your Function (your Macro) in that Project
Use that Project as a Library
Wherever (in a Spreadsheet) you need this Function (your Macro), add the Library and create a Function which calls the Library Function.
One alternative, if you really want a App which runs as Addon, then see here the reference for that.
Reference
Library

Related

Apps Script persistent variable across all scripts?

I am trying to get a variable to work in all instances of all scripts across my user account to prevent unwanted scripts in different documents running if the variable is set. I've managed to do this by creating a file on Google Drive but it's too slow really.
I know about PropertiesService but according to the documentation this seems to only be specific to the current script or document. Is there any fast way to create a persistent variable accessible from anywhere in the google account via apps script?
There are several options
Use a project to create installable triggers instead of simple triggers,
Use a library,
Create a Workspace add-on
Create an Editor Add-on
On any of the above use the Properties Service and getScriptProperties instead of copies of the same script.

Need help using a google script across all google spreadsheets

Need help using a google script across all google spreadsheets without copying script to each sheet. I've converted the script project to a cloud-managed platform and enabled all the APIs that I think are required.
I've deployed the script as add on and I see it on the add ons menu in sheets but I can't call my functions, etc.
Within one project you can have several different script files (You can create them by going to File>New>Script file). I suggest you distribute your functions and your logic across them the way you most prefer. Afterwards, any of those functions can be accessed by any of the other files declared in the project, so you should have no issue on calling them from i.e. your Add-on.
Additionally, you can use libraries. To do so:
Create a new Project (which will serve as a library). It may have multiple gs files, with multiple functions.
From the guest script, the one that will use the library, go to Resources>Libraries. There, insert your library project's id, and the identifier that will be used (variable name) to reference it. For the example below, I have set it to be MyMathLibrary (see example usage in Invoicing.gs).
Example project:
Project link: https://script.google.com/d/1kNeHHS7M19ILwcbbootMfZFNtg0NdE27WtkElXFBgOVR6haUUKPYqOBL/edit?usp=sharing
Library link:
https://script.google.com/d/12x33E1q3Uk2dgx5SfVTllVel8PeHcudQ-Czwhnu7aJPU5-tFpICuEcMM/edit?usp=sharing

how to share same app-script between multiple (different) spreadsheets in google spreadsheets

First of all I am after 3hours of reading docs about google cloud, publishing, projects and so on. After many tries i realized that i am missing something so here is my question.
I have two spreadsheets, lets, call it "prices" and "costs". What i want to achieve is that they share same app scripts and if I change one script, since it is shared by both it will automatically change in secons.
So i did create an app script that returns a string (just for simplicity) in a cell and called it STRINGFUNCTION(); Is is created in PRICES spreadsheet. My goal is to have it working in COSTS file without typing it manually.
I expected that if i click Resources > Cloud Platform Project and add both app scripts from both spreadsheets to the same project it will work automatically. Well, it wont - if i write in a cell =STRINGFUNCTION() in PRICES it works fine, and in COSTS - it says that function in not known.
How can I achieve that so it works between my both files and they share same function if they are both in same project?
You can do this by putting your code in a standalone script and use it as a Library.
https://developers.google.com/apps-script/guides/libraries
Here's how to do this:
Go to https://script.google.com/ and create a new project
Replace the code with the code for your custom functions and save
Click "Untitled Project" and give it a name to use for accessing the library
Click the blue Deploy button and choose New Deployment
Click the gear beside Select type and choose Library
Enter a description and click Deploy (this is what makes your Library available from other scripts)
Go to Project Settings and copy the script ID
Go back to your Spreadsheet, open the script for your sheet, click + beside libraries and paste the script ID and click Add
Remove the code for the custom functions if necessary and you're going to create functions to pass through the library functions
If your function is called STRINGFUNCTION(), create a function in the local apps script like this:
function STRINGFUNCTION(parameter) {
return libraryName.STRINGFUNCTION(parameter);
}
Do that for each function you want to use from the Library and save your code. You will need to authorize permission for the script if you haven't already. Now the custom functions should be available in your spreadsheet. Copy and paste this "pass through" script to each sheet where you want to be able to access the custom functions from the Library.
Custom functions inside a Library cannot be called directly from a sheet. You only have to set up this local script to pass through the functions, once. Now if you update the script in the Library, the updated functions will be available to the sheet. You will need to do the deploy set each time you make a change to the Library to publish the changes. If the changes aren't working in the sheet, click on the Library in the local script and make sure the version is Head or the latest version you published.
You can only bind a Google Apps script file to one document at a time. Apps script doesn't allow you to edit the contents of a .gs file on the cloud from inside another Apps script file, as trying to fetch:
var data = DriveApp.getFileById('script-id').getAs('application/vnd.google-apps.script');
will return the error:
No item with the given ID could be found, or you do not have permission to access it.
You could however bind the script to one spreadsheet, for example say the 'COSTS' spreadsheet, and create a second sheet within the spreadsheet for 'PRICES' with all the relevant function calls. In the separate 'PRICES' spreadsheet you could then use the build-in IMPORTRANGE formula to get the data from the 'PRICES' range from the first spreadsheet that has the bound script.

Using Google Apps Script Libraries

I have read all Google documentation on managing and creating libraries, yet I still do not know if they are an appropriate option for the problem I am trying to solve.
I know how to save a version of a standalone script. I know how to add the library to a spreadsheet via the script editor. But I don't understand, very simply, how to trigger the library script within the new spreadsheet.
I have a spreadsheet that serves as an often-copied template within my organization. The template contains a script that (onOpen) accesses data on a separate spreadsheet (a master database) and sets those values on a tab called "admin." The desired result is to have a copy of the master database living within the template sheet (and every subsequent copy of the template sheet). At this point, there are thousands of copies of the template sheet, each running that same script.
Whenever I have to change the script, I have to change it within thousands of sheets. Can I use a library instead? I'd like to be able to create a new version of the script in the library and have all sheets connected to that library experience the change. I understand that the library needs to be in development mode (within each sheet) to do this. I also understand that in order to make this switch, I will probably still have to go into each sheet to add the library. I'm just hoping it will be the last time I have to do such a tedious task.
Any advice or links to solid info is appreciated.
besides making an add-on (already covered in another answer) I will answer your libraries question. They will work for you. What you are missing is the "connect" part.
For this you want to trigger the library code from say, onOpen. The onOpen in the library is not enough and not detected by apps script. Instead each of your spreadsheet's script needs an onOpen(e) which just calls yourlibrary.onOpen(e).
since those "hook" calls rarely change, specially once you stabilize your library api, and using it in "development" mode will let you modify just the library.
whenever one of those hooks needs to change (say a callback from an html GUI needs a new parameter) you need to update all the spreadsheets. to avoid this, make all your callbacks receive a single json object instead of multiple parameters.
Sorry if I am repeating other answers, but I would like to sum up and add something:
You can access your library functions as follows:
From the app using the library you go to the Resources/Libraries. You can see the library name under "Identifier". On the same line where you can select Development mode.
Library name found in resources
Now in your library you have for example a function
function onOpen(e)
{
Browser.msgBox("HELLO!");
}
In the spreadsheet app you wish to access it you use the library name found in the resources, for example "testlibrary"
function onOpen(e)
{
testlibrary.onOpen(e);
}
Now if you have development mode on, the modifications to functions in the library update automatically to your application (spreadsheet) as long as the user using the application has edit access in your library script.
If anyone using your spreadsheet has a restricted access to your library script (meaning only view access) or development selection is off in the application, you have to go to the application's script, Resources/Libraries and select the most recent version of your library to be used in the app everytime you update the library and save a new version of it.
Still, especially if you are using mostly only the onOpen function , I would recommend using the library rather than copy-pasting the function to the script of each spreadsheet, as it is easier to track which scripts are up to date and it is easier to avoid errors and differences between the scripts.
Even in the more restricted case, if you update function in library - as long as you are already calling it in the app - all you have to do is select the new version of the library used.
I hope I had anything to give in this conversation and my language was appropriate, this was my first answer..
A good question Melly. I've been through a bunch of the documentation and some tutorials on this subject but haven't tried adding any libraries yet. My understanding is that once you are connected to a library all you have to do is call the applicable functions. That once a library is connected the functions in the library become an extension of all the other Apps Script classes available in the script editor.

How to publish custom function for Google Spreadsheets developed using Google Script

Please forgive me if I sound naive, I did read some tutorials on Google Script site.
I recently became aware of extending Google Spreadsheets functionality with custom functions using Google Script.
I understand the Script is tied to a particular Spreadsheet that one opens in Google Docs and using Tools menu to insert custom functions code. The Spreadsheet works like a container for custom functions code
The issue that I am having trouble understanding is how such functions are published and how do the end users discover availability of custom functions so that they can insert those custom functions in the spreadsheets they create
And is there a way to put together a collection of custom functions to work like a Functions Library or do we have to create individual functions and publish each one
As you've mentioned, a custom function's availability is restricted to the spreadsheet under which the custom function was written until recently.
You can now create Libraries of the functions and make them available for other spreadsheets to use by the script ID - More details in the documentation https://developers.google.com/apps-script/guide_libraries
If you publish your script to the Script Gallery it can be discovered and installed by other users. They will have a copy of the script's source installed into their spreadsheet.