Copying a Google Doc with a linked Sheet in it - google-apps-script

I have a Google Doc, within which I linked a Sheet. So, a table and/or a chart, that updates when the corresponding range in the linked spreadsheet updates.
Now, I want to make a copy of this document, so that the copy is linked to a (new) google sheet, which also is a copy of the original google sheet.
My first idea was using the Docs API to update some sort of reference, but it seems it's not possible to update an .. EmbeddedObject. I also tried using a Google Apps Script, but there I could also not figure out how to do this. I looked at a few more things, like creating a new doc using the Doc API, but I can't pass the inlineObjects or positionedObjects1, and apparently can't insert it afterwards either.
Did I just miss something? How can I make a duplicate of a Doc and a linked Sheet?
Any tricks, as hacky as they may seem, are very welcome!
1 While documents.create does accept both in the request body, the reference says "[...]any provided content, are ignored." (and indeed it is)

Related

How do you tell if a Google Sheet has script attached or not?

Is it possible to know, programmatically, whether a Google Sheets document has a script object attached?
After finding that out, I'm also interesting in knowing what properties can be discovered about the attached script and whether permissions for it can be discovered and defined?
The Sheets API on developerMetadata looks like a place one might start.
Unfortunately what you want cannot be achieved as there is no way to check if a spreadsheet has a script attached to it.
The only way to check if a spreadsheet and a script are bound together is the other way around: by checking from a script if there is any spreadsheet attached to it.
This can be done by using the getActiveSpreadsheet() method.
As for the developerMetadata, according to the documentation, this simply refers to the data from the spreadsheet itself associated with the developer metadata and has nothing to do with any scripts bound to it.
Developer metadata may be used to associate arbitrary data with various parts of a spreadsheet and will remain associated at those locations as they move around and the spreadsheet is edited. For example, if developer metadata is associated with row 5 and another row is then subsequently inserted above row 5, that original metadata will still be associated with the row it was first associated with (what is now row 6). If the associated object is deleted its metadata is deleted too.
It is also important to note that the script bound to the spreadsheet is not an object, therefore you cannot retrieve it.
What you can do in this situation however, is to file a feature request for the Sheets API following the link here and don't forget to include all the details that might be needed for this.

Recording any copies made of a google sheet

I would like to create a Google sheet that records any copies that have been made of another Google Sheet even when the user creates a copy by putting 'copy' into the URL (https://docs.google.com/spreadsheets/d/"spreadsheet-ID"/copy).
I have found a solution on the post: Track number of copies made from a google spreadsheet but this doesn't record copies made when changing the URL as the above example.
I would like to know the whole URL of the sheet preferably but just the Spreadhseet ID would still be enough for me.
Has anyone got any ideas how I can record all this data onto a spreadsheet please?
Basically you won't have access to see who is copying your sheet if you use the built-in Make Copy.
What you could do is integrate part of the question you have provided, while disabling the built-in sharing method. So the only way to copy your sheet could be through a custom function you can control and register every time it executes.

Navigation in published Google Sheets

I need to publish a report I have in Google Sheets, but since the report is very big, with many sheets and tables, I have hyperlinks set up for easy navigation, that take you to ranges in other sheets.
When I publish the sheet, the hyperlinks stop working (they take you to the first sheet in a new browser tab). I also tried with a script to change the pages with a button, but the button is not clickable in the published page.
Thanks for any tips you might have.
EDIT:
I've prepared a test sheet to see if I find a solution for this. This is a link with permissions to edit:
https://docs.google.com/spreadsheets/d/1ZGw_6WjrkcNKdFvS8gIG46gEMfMuw7ex86SR9C7qXTU/edit?usp=sharing
And this would be the published version:
https://docs.google.com/spreadsheets/d/e/2PACX-1vTa8JDNMzwdvk87kCvbjJXYgK2RGiKy503eJn6eEjxbyU8oIsuvuKTNXCM6yRP16KXrnD9yvLV3J488/pubhtml
This actually works in Excel, I can embed the report and the hyperlinks still work fine, but I have everything else in Google Sheets, so I'd like to find a workaround.
You need to use proper query parameters. The sheet id, gid must be set to navigate properly. You cannot use rangeid. You can however use range.
/pubhtml?chrome=false&gid=[YOUR_SHEET_ID]&range=A1:B1
You can get your sheet id by visiting your sheet(tab) in your spreadsheet (edit version) and inspecting the url.
Your published sheet probably retains the original #gid (which is Google's sheet ID used for local links). This will fail because it is linked to a Spreadsheet that is inaccessible to the new report. Please check if this is the case (you'll see in the links you've created). I can understand that you won't want to share the original reports but you can set up a small test Spreadsheet with a few linked sheet ranges to test the process - please share that.

Looking to create a Google App Script that duplicates a complicated sheet? Ideas?

In the end, I want to make a script that creates a folder that has other folders in it with a bunch of copies of a custom data sheet our school is using for data analysis.
As of now, I have created a whole system of Google Data Sheets that are connected through the IMPORTRANGE feature of Google sheets that our school uses to compare data. I would like to implement this system in other schools and wanted to try and write a Google App Script to set it up.
I have a couple of questions:
Is it possible to use a script to create a document is automatically set up to use the IMPORTRANGE feature to import data from another document?
If I have a sheet set up already (the standard data sheet we use) that I want to make 400 copies of in different folders, do I have to code the script to generate this document from scratch? Do I code it to pull a copy from somewhere? What do you guys think?
Does this even seem like something that's possible?
Thanks so much for your help guys!
Brandon
Sure. After you create the document, you'll just insert =IMPORTRANGE() using setFormula() or setFormulas(). You will have to manually grant permission for the sheet to import ranges the first time you open it, and any time after when you insert =IMPORTRANGE() with a reference to a new sheet, though.
This is no problem either. You can use the Drive Service and makeCopy() to copy a file into a destination folder you specify.

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.