Google Apps Script: Get the ID of script bound to a spreadsheet - google-apps-script

I want to write a Google Apps Script to generate a list of the IDs of the scripts bound to certain spreadsheets.
I cannot find a way to programmatically, via GAS, get the ID of a bound script.
If I have a spreadsheet object, I have methods like getId to get the ID of the spreadsheet, but not the bounded script.
Using the DriveApp, I can find standalone scripts using DriveApp.getFilesByType('application/vnd.google-apps.script') but not bound ones!
Any suggestions?

Unfortunately (by my own research) this is not currently possible. I have been wanting to programatically identify and access bound scripts for several years, I look into it periodically, I've always come up empty handed.
Haven't found any Google documentation explicitly on the topic, still hoping this hole gets filled eventually.

Related

Updating multiple appscript projects from one appscript

I have scenario where I have more than 60 sheet, and all have appscript project behind them running and managing those sheet.
I want to updat/control those appscript projects all at once, from one different project. So that I don't have to manually go and update them.
I know this solution where we can update it by manually getting OAuth Token from single appscript project but, Is there any way we can just mention sheetID and it updates project behind all those sheet all at once?
From the question
Is there any way we can just mention sheetID and it updates project behind all those sheet all at once?
There is no direct way to do this. Related issue Retrieving Project ID of Container-Bound script (created in 2018, as of the end of 2021 it still has the "New" status).
Assuming that by "SheetID" you mean the spreadsheet id, it's possible to use the Spreadsheet Service and the Drive Service to get a Class Spreadsheet or Class File object, respectively. Unfortunately those classes hasn't any method to retrieve the bounded Google Apps Script project.
The same for the Sheets API, Drive API and the Apps Script API.
The indirect way is to build a list of spreadsheets and their respective bounded scripts but it's clear that this is not what you are looking for. Anyway, build the list of spreadsheet/script projects pairs and store it somewhere (it might be an spreadsheet if the list is not humongous. CLAPS has a command to retrieve the list of the recent projects, and it's possible to get the container id from the script project metadata (see https://developers.google.com/apps-script/api/reference/rest/v1/projects/get)
Considering the above, the advice to make it easier to maintain your scripts "for the next time" is to either use a library or to create and add-on.
Resources
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
https://developers.google.com/apps-script/reference/drive/file
https://developers.google.com/apps-script/api/reference/rest/v1/projects#Project
Related
How to programmatically create a list of Google Apps Script projects owned by me?
List Google app script projects
Google Apps Script: Get the ID of script bound to a spreadsheet
How to make Google Apps Script library always serve the latest version
If you're asking can you reference different codes from the same document but not the same sheet in a new code, the answer is yes. But, there is no way to manipulate this code other than editing the original code. I would recommend manually getting an OAuth Token from a single Apps Script Rroject.
A different way to control those Spreadsheets can be with a NodeJS project locally, using Clasp and Multi-clasp2 (https://www.npmjs.com/package/multi-clasp2).

Can I link a script to a google sheets which already has a script?

I have a google sheets which is linked to a form and a google scripts that was created in the menu of google sheets. This script runs fine and I use it to format the data. However, I have another script which I created from the google developer console, which sends and receives data from a website. I need this second script to get the value of a cell in the google sheets.
How can I link this second form to the google sheets while keeping the script already linked to the sheets?
When looking at responses to other questions they seem to be about individual sheets in a set so just to clarify, when referring to google sheets I mean the whole google sheets document. I only have one sheet anyways.
If it helps: The script I want to add acts a bit like a server and is being deployed by google scripts while the script that is already linked is only run when I call it on the sheets.
There is not way of attaching a standalone script to a document making it a bound script (which is the actual terminology for the script linked the the document).
The simplest way would be to copy-paste the code to the other script. You can deploy the bounded script.
If you really need more than one project for whatever reason, you can enable the Apps Script API and use projects.create (read reference) to create another one. If you don't know what this means, you probably shouldn't use it as it's finicky at best.
I found a solution which was to link the script to the google sheets using
var ss = SpreadsheetApp.openById("SHEET_ID_HERE");
I can then use ss.getActiveSheet().getRange().getValue();
and other funtions.
Thanks for the help!

Can an apps script macro in a Google sheet be used by other users?

I have a fairly simple requirement for a Google sheets apps macro script - it basically pulls the values from a couple of cells in another sheet and displays them in an alert box.
I've done the macro for this and it works fine. What I now want is for anyone I've shared the sheet with to be able to run the same macro. This is where things have suddenly got a bit more involved! My questions are:
Is this possible? And if so, what's the best way of achieveing it? At the moment, the macro is not available for the test user I've shared the sheet with. I've had a bit of a look around and it seems like publishing the script as a web app may be the way to go - can anyone confirm if that is correct? Or would there be a better option? I don't know anything about web apps so just want to confirm if this is the best option before trying to wrap my head around it all.
If the sheet in question has been shared with a user, but the second sheet which the script pulls data from has not, is it still possible for the user to run the script and retrieve the data? Or would the second sheet need to be shared with that same user as well? (If it would then it kinda defeats the object of what I'm trying to achieve).
Finally, would the user with whom the sheet is shared have to have a Google account in order to do this? I'm assuming so...which is a bit of a pain, but I guess understandable.
Thanks very much
Wokaround
Following the requirements you have described I get that you want your users to trigger an Apps Script function that will alter or get data from your Spreadsheet while only granting your users viewer-only acccess.
As described here only users with editor level access can run functions on your bounded script or activate it when clicking a button in your Spreadsheet.
To overcome this you can create a simple web app with a button that will trigger your function. Users will have to access this web app to trigger the function. The good point is that they will not have editor level access to the Spreadsheet nor to the actual script of the web app (as they will just interact with its user interface).
The web app would be a different script that can interface any of your Spreadsheets editing them or getting any information from them.

How can I add a Google apps script to a spreadsheet created using the API?

After reading up a lot on the Google Spreadsheet API I have come to the conclusion that formatting (such as merging cells, changing fonts etc) is only available throught the Apps scripts.
Since we need to create and fill the spreadsheets with data programatically using Java on the back-end I guess I need to somehow either;
link the new sheet to a Apps script that trigger on-load or
create a Apps script that creates the spreadsheet for me.
Anyone knows?
If you want to just "create" the spreadsheet, you don't need a script to load whenever it spreadsheet is opened. It's probably easier to develop a script that runs once and create the spreadsheet for you.
Another tip is to have a template file that you can copy with most of the formatting (if not all) already there. Possibly pending just little things that are related to the real data the new spreadsheet will have.
Edit to answer the question in the title.
No, you can not add a script to an existing spreadsheet programatically, only manually. What you can do is previously set up a template spreadsheet with a script in it and create new spreadsheets by copying this template.
(answering the comment)
You can run a script programatically, but not upload it. To run a script you can deploy it as a web-app and call its url with either a http get or post (will call its doGet or doPost functions, that you must have declared). Also, you could set this script to run on form submit of any spreadsheet-form and just submit a set of answers to this form. At last (that I can think of now) you could just add the script as a library in another Apps Script and call it directly.
(Aug 2016) There is no way programmatic way to link a Google Sheet and Apps Script code other than manually. Based on what it seems you want ("create and fill the spreadsheets with data programatically using Java"), you can now do it without Apps Script.
TL;DR: Above, #Henrique has answered multiple questions and even questions that weren't asked! The good news is that today, we have more answers representing alternate possible solutions to what you're seeking.
It's now possible to "upload" Apps Script code programmatically with the
import/export system, say with Eclipse since you're a Java developer (2013 announcement).
I agree with Henrique's suggestion that if you create a spreadsheet
template, i.e., Excel file, you can use the Google Drive API to
programmatically import/create identical Google Sheets with all your
desired formatting.
"Formatting (such as merging cells, changing
fonts etc)" can now be done outside of Apps Script, as there is a
"new" Google Sheets API v4 (not GData).
In order to use the new API, you need to get the Google APIs Client Library for Java and use the latest Sheets API, which is much more powerful and flexible than any previous API. Here's one code sample to help get you started. If you're not "allergic" to Python, I also made a video with a different, slightly longer example introducing the new API and gave a deeper dive into its code via a blogpost that you can learn from.
Note the v4 API allows you to create spreadsheets & sheets, upload & download data, as well as, in the general sense, programmatically access a Sheet as if you were using the user interface (create frozen rows, perform cell formatting, resizing rows/columns, adding pivot tables, creating charts, etc.), but to perform file-level access such as uploads & downloads, imports & exports (same as uploads & downloads but conversion to/from Google Apps formats), you would use the Drive API instead.

Is it possible to have one script for multiple spreadsheets?

I have one master spreadsheet and a number of copies. This master spreadsheet uses some scripting.
Is it possible to link all the copies of this master spreadsheet to the same script as in the master spreadsheet?
Objective:
changes in the scripting in the master spreadsheet are automatically used by the copies
aka: low maintenance
amleczko is right: you should use the new library feature in Google Apps script.
However, as of today, you won't be able to do exactly what you want (using the same script for several spreadsheets). What you can do instead is save a version of your script (Files > Manage Versions...), in order to create a library. Then, import this library in the other spreadsheets (Resources > Manage Libraries...). Switch on the "development mode" so every change made do the library will immediately take affect in the spreadsheets using this library. Otherwise, you will have to save a new version of the library for every change, and manually update the version number of the library in every spreadsheets using it.
The problem is, you need to write a script in every spreadsheets using your library, with skeleton functions like this:
function doSomething(){
myLibrary.doSomething();
}
best way is to publish as add-on, then install the add-on, it will appears in every spreadsheet you open. and you can publish as private, which only seen by yourself.
I think this has changed. According to Issue 40 starting from 22 May 2012 there is such a possibility. Please check:
https://developers.google.com/apps-script/guide_libraries
https://developers.google.com/apps-script/guide_versions
http://googleappsdeveloper.blogspot.it/2012/05/introducing-versions-and-libraries-in.html
It's not possible in this way that you're thinking. At least, not yet (see issue 40).
But, depending on your script usage, you may connect them "the hard way" or even better, use only one script. The script on the master spreadsheet can open the other spreadsheet files and do its job "remotely". It's not required that script to be hosted on a spreadsheet to interact with it (read/write on it). You only need a script hosted on the spreadsheet if you're going to use spreadsheet events triggers i.e. on-open, on-edit and on-form-submit.
Maybe you can develop a nice UI for the script on the master sheet and publish it as service. Then only have a link on the copies to access the same UI on a different browser tab. Adding parameters to the link the script UI can even adapt to the particular spreadsheet that is "triggering" it.
Well, that's all I can imagine now. But, unfortunately, there's some use cases that just don't fit this nice "workarounds". For those, one can only star issue 40 (to kind of vote and keep track of updates) and hope it's developed soon.
The solution I put in place in this context was to have a Google Site, where the Master Script is embedded, and where the Spreadsheet is embedded too
Then, the script, refering to a dedicated spreadsheet, looks for the Google Site Page's name, looks in the Master spreadsheet and get the ID of the spreadsheet which is embedded in the Page.
I have solved this problem when using a script which auto generates spreadsheets.
Typically, I will add a sheet to any spreadsheet with a script called "Info." I'll use that to store information that it important to the script. In my script which auto generates more spreadsheets, I keep track of the ID of the created sheet. This way, I can then quickly call up all of the "linked" sheets, and interact with them with using the same script. It might even be worth writing the script in one sheet, and keeping it totally separate from your Master sheet or it's children.
Take a look at this function, it might give you some ideas.
SpreadsheetApp.openById(id)