How to copy triggers/projects from one spreadsheet to another? - google-apps-script

I'm attempting to create a spreadsheet that needs to be copied a bunch of times from within one spreadsheet but each copy is also meant to have triggers within it and it appears that this is harder than I initially thought.
The actual project involves an editable database that takes from single sheet spreadsheets each one a copy of a single sheet from the main spreadsheet and the whole thing then needs to be duplicated.
I first just tried to create a copy of the first spreadsheet but it seems that the project that the triggers are contained within doesn't copy over. I have tried using installable triggers but it seems that you cant do this easily from within another spreadsheet as explained here (I don't really understand the answer to this question). I have also looked at the possibility of copying the project from one spreadsheet to another but this also just seems like a dead end.
I can appreciate that this is quite vague but I really have no idea what to do about this and any suggestions would be appreciated.

Hmm I am not sure about copying triggers over. (I normally just use onOpen triggers for menu items.) However I can confirm the following bit of code copies the spreadsheet and all of it's embedded scripts.
function copyTemplate() {
//A file needs a name
var fileName = "Your File Name Here"
//Get the ID of the Master Spreadsheet (This script is embedded, you can change to get by id.)
var id = SpreadsheetApp.getActiveSpreadsheet().getId();
//Get the Destination folder by ID
var destFolder = DriveApp.getFolderById("YOUR_ID_HERE")
//Get the master template, make a copy in the destination folder.
DriveApp.getFileById(id).makeCopy(fileName, destFolder)
}//END OF FUNCTION

Related

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.

Google Spreadsheet run script slow

Let's say I have a spreadsheet called A. When i run a script on spreadsheet A it will load very slowly and may cause timeout sometime. (I thought something was wrong with the function I created so i improved it - but still causing same result). However, once I make a copy of spreadsheet A (name it B). With the exact same code and functions spreadsheet B runs script rather fast. How is that possible when spreadsheet B is the exact same as spreadsheet A?
I found out what was the problem. It is actually because of getScriptProperties in my google spreadsheet. So, in my old spreadsheet the getScriptProperties will take old data (whereby, when i create a new one, i does not exist). On the other hand, when I duplicate a new spreadsheet, it is running for the first time so it will take everything. What i did was deleteProperty of the old spreadsheet so that it can create a new Script Property (which will take new additions).
The code is as below:
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.deleteProperty('test');

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.

Some spreadsheet cells not updated before trigger function sends email

I have a spreadsheet which extracts and accumulates all the required data from other 6 spreadsheets using Vmerge and Query formulas and all the consolidated data will be converted to pdf and emaild to mail ids using trigger event.
Here begins the problem every time the attachment mail posted consist all the headers and other format, but the data which is extracted does not appear. It seems to appear like - to open the same spreadsheet, after a while all the - (hyphens) are replaced by the data / Hope all the data updates after a while of opening the spreadsheet.
link for sheet
Can anyone direct me to make this issue sorted out.
For this solution should be -> all the data should be updated and then the email script should work; or either it should update before emailing script starts.
Or any other better ideas are appreciated.
Some spreadsheet formulas, like ImportRange and ImportXml (and also Apps Script custom formulas) are only evaluated when there's someone logged in the spreadsheet. It's like these functions need an account to be evaluated from, for example, in importRange the account logged in must have access to the range being imported, if you share this spreadsheet with someone but not the importRange source, when this person is viewing this spreadsheet, the importRange function will not work (well, unless you're also in the spreadsheet and the formulas have already been evaluated).
Bottom line is, you can't have this formulas and use a script triggered on time-driven (or other trigger that does not require someone logged in) and expect the script to be able to read this data.
The workaround though is quite simple. Do what the importRange function does inside your script! e.g.
var source = SpreadsheetApp.openById('source-spreadsheet-key');
var data = source.getSheetByName('List').getRange('I6:AT500').getValues();
//then save it somewhere
var s = Spreadsheet.getActive().getSheetByName('hidden-import');
s.getRange('I6:AT500').setValues(data);
SpreadsheetApp.flush(); //force the data to be written
//so all the other formulas on your spreadsheet get updated with the new data
All your "logic" formulas, like query and vmerge, which are difficult for the script to mimic, can be left on the spreadsheet, but reference this "hidden-import" sheet I just invented instead of nesting importRange directly.
[edit]
To copy only non-empty rows do like this:
var data = SpreadsheetApp.openById('source-spreadsheet-key').
getSheetByName('List').getDataRange().getValues();
Spreadsheet.getActive().getSheetByName('hidden-import').
getRange(1,1,data.length,data[0].length).setValues(data);