Recording any copies made of a google sheet - google-apps-script

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.

Related

Automatically keep one sheet synchronized with another

I have a Google Sheets that I'm working with, and for reasons I'd rather not get into here I need to keep an updated copy of it in a second location. The original spreadsheet has two sheets/pages, I only need to copy from the second sheet/page to the first sheet/page of the new spreadsheet.
I have a server that can accomplish this if an API is necessary. I don't need an exact script to do it, but pointing me in the right direction would be very helpful. I'm most familiar with Python and PHP if they're needed.
I'm sure there is an easier way to do it using Apps Script, but if you want something that works in the short-term while you learn Apps Script, you can use the IMPORTRANGE function and Sheets exclusively.
=IMPORTRANGE("SpreadsheetKey","Sheet!Range")
Example:
I created a sheet called OriginalSheet and in A1:A5 put the numbers 1 through 5.
Next, I created a separate sheet called NewSheet and in cell A1, I put the the following function (with appropriate values for my OriginalSheet filled in):
This method works for me. I'm in the process of learning Apps Script and will post a better method when I learn it :)

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.

Publishing / sharing a Google Sheet via Github

I have a Google Sheet. It has a custom script (read: set of functions) associated with. I'd like to share this sheet template (i.e., tool), not with colleagues (i.e., adding them via email address as is a traditional Google drive share) but with anyone who would like a copy for themselves to use it for themselves (i.e., not my copy, their own copy). Ideally, I'd repo this project / tool on GitHub (or similar) and let them grab it there.
I can "Download As..." the sheet but the script doesn't stay "attached". Are such scripts now what Google considers Add-ons? If so, how to I keep the sheet + script as a "whole".
Also, as a temporary workaround, I tried to copy / paste the script from my working copy to another copy of the sheet (created via Download as and then opened again under a diff Google accnt). However, that didn't go as planned either. There's a function within my scrip that checks to make sure the sheet is on the first tab / sheet (i.e., getActiveSheet().getSheetId() == 0). This works on my dev / working copy. However once I copy / paste the SheetId return a 7 or 8 digit #. Is there a way to keep the SheetId relative to the sheet, and not all sheets (or whatever that Id represents.)
Note: I'm by no means a Google Sheets expert. This was just a side project for myself that I ended up building out to the point of wanting to share it with others. Please presume I know even less than you probably think I know. Thanks :)
To fix your problem with finding the first tab / sheet, use the sheet index instead of the sheet id. So instead of getActiveSheet().getSheetId() == 0, it'll be getActiveSheet().getIndex() == 0 instead.
As for downloading the script - it looks like you've created a container-bound script. There are two types of scripts that you can create, standalone and container-bound scripts. (See Google's explanation here). Standalone scripts are created by going directly to script.google.com, but I'm guessing (please correct me if I've assumed wrong) that you clicked Tools->Script editor, so that the script is locked to that specific spreadsheet. That's fine, but a) it means like you can't download it separately through Google Drive as I originally suggested, and b) when you're download the sheet, it downloads it as an Excel worksheet (which doesn't support Google App Script, so of course the script doesn't come with it).
Here's my suggestion for your use case:
Instead of downloading the spreadsheet, make a new copy of it named yourspreadsheet_public or something along those lines by going to File -> Make a Copy. (You can potentially skip this step if you just want to make your personal spreadsheet available to the world.)
Make the copy available to anyone to view by clicking Share -> Change -> Anyone with the Link (or Public on the Web) -> select "Can View" from the dropdown -> Save.
Now, you can distribute the link to whoever wants it. Anyone who has access to the file is able to make a copy in the same way you did in the first step to their own Google Drive, where they'll be able to edit their own private copy, including your script.
Let me know if that helps!
I don't understand why you want to use an external service to make copies of a spreadsheet. Since Google Scripts only run in Google spreadsheets I don't see any use case where it can be useful... but that's not the point, you do what you want.
That said, the easiest (and probably the only) one would be to share the document with someone and create an onOpen function that suggests to create a copy of it. This script should be executed after the required authorization and the copy will be their own copy, without any link to your G account anymore (which was the goal if I understood you well).
More simple and straightforward than that I can't imagine.
To avoid that their copy keeps the same onOpen behavior just setup a variable stored in userProperties so that when present this part of the onOpen doesn't execute.
This is a workflow I have already used and it works nicely.
edit :
I can suggest a completely different workflow to let other people get a personal copy of your SS.
Here is a test , give it a try and let me know if you're interested.
EDIT2 : since the other answer provides a similar workflow I decided to show the code I use in this answer to make that process more userfriendly.
I use 2 webApps :
one that runs as "me" that have access to my drive and runs without authorization for its user and that does nothing else than show a warning and a link.(accessible to anyone even anonymous)
And a second one that creates the copy and needs authorization to allow the SScopy creation in the user's own drive + a couple of links.(runs as the user accessing the app)
Code below (in 2 distinct projects of course) :
// APP 1 :
function doGet(){
var app = UiApp.createApplication().setTitle('Demo-App');
var link = app.createAnchor('Click this link to create your own copy <br>of my spreadsheet.<br>You will be asked for authorizations<br>tocreate a spreadsheet in your drive',true,'https://script.google.com/macros/s/AKfycbwQ5s_WWrsWXx_umZ1v91XGnm3RaO2Z7UQSXNiWFiaTwGuXIXqq/exec');
app.add(app.createVerticalPanel().setStyleAttribute('padding','50px').add(link));
return app;
}
// APP 2
function doGet(){
var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dGNEUDdoLWhUZl9sZ3Z2Zm5XbjZzTkE');
var copy = ss.copy(ss.getName()); / the SS is shared to "anyone with the link can view"
var app = UiApp.createApplication().setTitle('SSCreate');
var panel = app.createVerticalPanel().setStyleAttribute('padding','50px');
panel.add(app.createHTML('A new spreadsheet has been created in your drive with name '+ss.getName()));
panel.add(app.createAnchor('Open it from <b>here</b>',true,copy.getUrl()));
panel.add(app.createAnchor('or from your own Drive','https://drive.google.com/?authuser=0#all'));
return app.add(panel);
}

How do I copy a script from one spreadsheet to another spreadsheet?

I need to copy an existing script, which I did not write, into my existing spreadsheet. The script is called "SaveBack", and can be found here: https://docs.google.com/a/levelgroup.com/spreadsheet/ccc?key=0Agcb8bUVVOOodHhoV3BrRGZ6UEdSYnVLSEk3bllxRnc#gid=1.
My existing spreadsheet is too complex (it has many other spreadsheets that link to it) to copy all of its sheets into the spreadsheet that contains the script. I have already copied the SaveBack editor sheet template sheet to my main spreadsheet, but I can't figure out how to copy the SaveBack script that goes along with it into my spreadsheet.
Can anyone help? Thanks!
Open the save back script, select the script text, copy it, go to your sheet, create a new script (blank template), paste the script you copied into your new script, name is SaveBack (assuming it's a project), check the triggers on the original script and make sure your triggers match, and you should be good to go. You will have to change any sheet, document, or other string ID's to match your files' Id's, but that isn't too bad.
I do this sort of thing all of the time when I'm migrating things back and forth between my work and personal account. You could also create a copy of the other person's spreadsheet that you linked above, and it will move the script over with it. Then you can go to the script and get the project key to use it as library in your own scripts. Since you're using your copy as the library, you don't have to worry about someone else changing the script and breaking your functionality.

script to force republish of google spreadsheet

I have created a form that pushes data to a Google Spreadsheet. The data is latitude, longitude, location, and other identifying data. The spreadsheet is then published as a .CSV file and imported into ARC GIS to be displayed on an interactive map. It works exactly as I wanted and I set it to republish after each change.
The problem is that when the spreadsheet has rows appended by the script, it is not seeing it as a change and republishing. In order to get the updated data imported to the map, I need to go in and manually republish. Is there anyway through the Google Apps Script that I could make a few lines of code to force a republish? I could then add that to the "on form submit" script I have or another time based one that already runs at 3 am everyday.
I have looked through the Google Apps Script documents and not found anything. When searching for help on the web, the overwhelming majority of responses are for how to publish your script as a template for other.
My testing sheet was republished after the following function was executed by either a menu entry or a time-based trigger.
function ChangeIt() {
var sheet = SpreadsheetApp.getActiveSpreadsheet()
var t = new Date()
var x = 'upd: ' + t
var range = sheet.getRange('a3')
range.setValue(x)
}
If I were in your shoes, I'd add an extra column to the end of the sheet with some benign constant data that a script can change without affecting the systems consuming the data. If an extra column isn't an option, try modifying my sample to read in a current value, change it, and immediately change it back.
Also, I'd see if the spreadsheet onEdit() trigger fires when the form submit adds a new row. If so, tie your GAS function to it to force the republish. If not, setup a timed trigger to execute the GAS function.
A quick workaround for this issue that doesn't require scripting is to simply make an array copy of the data.
For example, I made a new tab and in A1 put this: =ArrayFormula('Form Responses 1'!A1:Z1000)
While the main Form responses tab will insert rows and not play nice with formulas this new tab stay nice and constant and updates automatically when new data is added.