Copy content from one spreadsheet to another without IMPORTRANGE - google-apps-script

I'm trying to create bidirectional synchronisation of some content between two Google Sheets. My script is working when:
the source and destination ID of the sheets are the same AND have the ID of the active spreadsheet
SO, THIS WORKS:
function myFunction() {
var sourceSpreadsheet = SpreadsheetApp.openById("ID-OF-ACTIVE-SPREADSHEET");
var destinationSpreadsheet = SpreadsheetApp.openById("ID-OF-ACTIVE-SPREADSHEET");
var sourceSheet = sourceSpreadsheet.getSheetByName("sheet1");
var destinationSheet = destinationSpreadsheet.getSheetByName("sheet2");
var sourceRange = sourceSheet.getRange("A1:A4");
// destination, columnStart, columnEnd, rowStart, rowEnd
sourceRange.copyValuesToRange(destinationSheet, 2, 2, 3, 7);
}
But when I replace the destination ID with the ID of another spreadsheet, it doesn't work.
Could it have something to do with permissions?
I have tried to publish both spreadsheets.
THIS DOESN'T:
...
var sourceSpreadsheet = SpreadsheetApp.openById("ID-OF-ACTIVE-SPREADSHEET");
var destinationSpreadsheet = SpreadsheetApp.openById("ID-OF-ANOTHER-SPREADSHEET");
...
Since I'm trying to create bidirectional sync I don't think I can use IMPORTRANGE.
Source SpreadSheet
Destination SpreadSheet

It seems like copyValuesToRange doesn't communicate outside the spreadsheet, here is a working solution:
function onChange() {
var sourceSpreadsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sourceData = sourceSpreadsheet.getRange("A1:A8").getValues();
var targetSpreadsheet = SpreadsheetApp.openById("ID-OF-ANOTHER-SPREADSHEET").getSheetByName("Sheet1");
targetSpreadsheet.getRange("A1:A8").setValues(sourceData);
}
PS: this also enables bidirectional sync between spreadsheets, just add a copy of this code on both spreadsheet A and B and replace "ID-OF-ANOTHER-SPREADSHEET" with the ID of the other spreadsheet. And then define the from- and to range in place of the "A1:A8".

Related

How do i copyPaste through AppScript into another file instead of a sheet

Right now I am using this formula to copy and paste to another Sheet. Though due to the file getting bigger and bigger, we want to place it in a seperate file which we dont really have to open.
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
var pasteSheet = ss.getSheetByName("CopyPaste");
// get source range
var source = copySheet.getRange(3,3,300,6);
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+2,1,500,4);
// copy values to destination range
source.copyTo(destination);
// clear source values
source.clearContent();
}
I tried to use getsheetbyURL instead. This did not work as it gave an error.
I also tried to find more information on https://developers.google.com/apps-script/reference/spreadsheet/sheet#copyTo(Spreadsheet). Though I cannot find an clear answer here.
I tried to add another "var" but "var sss = SpreadsheetApp.getActiveSpreadsheet. And then put pastesheet = sss.getsheetbyURL". This didnt work either.
I understand the things in the code which I have now. I only need to find the correct string.
I believe your goal is as follows.
You want to copy C3:H302 of a source sheet of Spreadsheet "A" to the last row of a destination sheet of Spreadsheet "B".
You want to use Spreadsheet URL for retrieving the Spreadsheet.
In this case, when your showing script is modified, how about the following modification?
Modified script:
function copyInfo() {
var destinationSpreadsheetUrl = "###"; // Please set your Spreadsheet URL.
var destinationSheetName = "###"; // Please set the destination sheet name.
// Source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
// Destination sheet.
var dstSS = SpreadsheetApp.openByUrl(destinationSpreadsheetUrl);
var dstSheet = dstSS.getSheetByName(destinationSheetName);
var temp = copySheet.copyTo(dstSS);
temp.getRange(3, 3, 300, 6).copyTo(dstSheet.getRange(dstSheet.getLastRow() + 2, 1));
// clear source values
copySheet.getRange(3, 3, 300, 6).clearContent();
// Remove temp sheet.
dstSS.deleteSheet(temp);
}
When this script is run, the values of "C3:H302" are copied from the source sheet of the active Spreadsheet to the destination sheet of another Spreadsheet. And, "C3:H302" of the source sheet is cleared.
If you want to use Spreadsheet ID, please use SpreadsheetApp.openById() instead of SpreadsheetApp.openByUrl().
If you want to copy only the values, I thought that getValues and setValues can be also used.
References:
openByUrl(url)
copyTo(spreadsheet)
Added:
From your following reply,
The formula itself works which is great. But it seems to take the formulas and not only the values. See picture: i.imgur.com/VRYCuTP.png . This causes an error since this file is not aware of any sheet named X. Would there be a way to only copy the values?
In this case, how about the following sample script?
Sample script:
function copyInfo() {
var destinationSpreadsheetUrl = "###"; // Please set your Spreadsheet URL.
var destinationSheetName = "###"; // Please set the destination sheet name.
// Source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Kenmerken Script");
var temp1 = copySheet.copyTo(ss);
var r = temp1.getDataRange();
r.copyTo(r, { contentsOnly: true });
// Destination sheet.
var dstSS = SpreadsheetApp.openByUrl(destinationSpreadsheetUrl);
var dstSheet = dstSS.getSheetByName(destinationSheetName);
var temp2 = temp1.copyTo(dstSS);
temp2.getRange(3, 3, 300, 6).copyTo(dstSheet.getRange(dstSheet.getLastRow() + 2, 1));
// clear source values
copySheet.getRange(3, 3, 300, 6).clearContent();
// Remove temp sheets.
ss.deleteSheet(temp1);
dstSS.deleteSheet(temp2);
}

Is possible to copy a data range from one spreadsheet to another?

function transferDataToDataBase(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var DB = SpreadsheetApp.openById("SHEET ID");
var SCPM_Input = ss.getSheetByName("Report")[0];
var history_Input = DB.getSheetByName(Database);
var blankRow = history_Input.getLastRow();
SCPM_Input.getRange(("A2:T").copyTo(history_Input.getRange(blankRow+1,1,blankRow+1,20));
}
Question:
The last line has an error at ";", don't know how to fix it. It said the syntax error;
It seems copy To only works for transferring from one sheet to another in the same spreadsheet, but not in between spread sheet. Is there a way to copyTo between spreadsheets?
Many thanks.
If you want to copy the formatting as well then copy the entire sheet/tab and then use copyTo() to copy the range and then delete the copied sheet. Or if you just want the data use getValues() and setValues();
This is part of the problem:
var SCPM_Input = ss.getSheetByName("Report")[0]; because the index zero at the end should not be there and you cannot have sheet.getLastRow() + 1 number of rows in a sheet as shown in the next row.
SCPM_Input.getRange(("A2:T").copyTo(history_Input.getRange(blankRow+1,1,blankRow+1,20));
And copyTo doesn't work between spreadsheets.
There is an update:
Since the database will be used by multiple users. I set up a standalone database. I copied my "Report" sheet from spreadsheet 1 to spreadsheet 2. It will create a sheet "copy of Report".I rename, copied to Database sheet and delete it.
Feel free to discuss if there is an easier way to do it. Thanks.
// transfer the report to DataBase Spreadsheet
function transferDataToDataBase(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var db = SpreadsheetApp.openById('spreadsheet ID')
var scpm_Input = ss.getSheetByName("Report");
scpm_Input.copyTo(db);
Utilities.sleep(3000);
db.getSheetByName('copy of report').setName('Import')
var history_Input = db.getSheetByName('Database');
var blankRow = history_Input.getLastRow();
var target = db.getSheetByName('Import');
target.getRange("A2:T").copyTo(history_Input.getRange(blankRow+1,1,blankRow+1,20));
history_Input.getRange(blankRow+1,21).setValue(new Date()).setNumberFormat("yyyy-mm-dd h:mm") //update the date and time
db.deleteSheet(target);
}

Google Apps Script - copy to existing spreadsheet

I'm attempting to use Google Apps Script copy() to 'publish' my master spreadsheet to an output spreadsheet, but getting multiple copies each time instead of it replacing the output file. Can anyone suggest a way to replace the contents of a destination spreadsheet so I can keep the same file-ID for the output and manually trigger a 'publish'. Have tried copyTo, but just makes multiple sheets instead.
The master spreadsheet is a staff roster that needs to be able to be worked on by multiple managers without staff seeing the live version. When the manager has finished updating, it can be pushed to staff.
Edit: Got it working
function publishRoster() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getActiveSheet();
var updatedDateTime = sheet.getRange("A1");
var now = Utilities.formatDate(new Date(), "GMT+10:30", "dd/MM/yyyy H:mm")
updatedDateTime.setValue("Last Published " + now);
var sourceName = source.getSheetName();
// var sValues = source.getDataRange().getValues();
var destination = SpreadsheetApp.openById('my-destination-sheet-id-here');
var destinationSheet = destination.getSheetByName(sourceName);
if (destinationSheet == null ) { }
else { destination.deleteSheet(destinationSheet); }
sheet.copyTo(destination).setName(sourceName);
}
copyTo() creates a copy of existing sheet in the destination spreadsheet.
If you want to publish the changes from a specific sheet to specified destination sheet then you can copy the data from source sheet to destination sheet, instead of copying the whole sheet.[which will of course create new sheets each time you copy]
So the code to copy/publish data from master sheet to slave sheet goes as follows :
var SOURCEID = 'xxxxxxxxxxxxx'; //put your source spreadsheet id here
var SOURCESHEETNAME = 'XXXXX'; //put your source sheet name here
var DESTINATIONID = 'xxxxxxxxxxxxx'; //put your destination spreadsheet id here
var DESTINATIONSHEETNAME = 'XXXXX'; //put your destination sheet name here
var data = SpreadsheetApp.openById(SOURCEID).getSheetByName(SOURCESHEETNAME).getDataRange().getValues();
SpreadsheetApp.openById(DESTINATIONID).getSheetByName(DESTINATIONSHEETNAME).clear(); //This line is to clear the existing data in destination.
SpreadsheetApp.openById(DESTINATIONID).getSheetByName(DESTINATIONSHEETNAME).getRange(1, 1, data.length; data[0].length).setValues(data);
//data.length = no. of rows in source
//data[0].length = no. of columns in source
var now = Utilities.formatDate(new Date(), "GMT+10:30", "dd/MM/yyyy H:mm");
SpreadsheetApp.openById(DESTINATIONID).getSheetByName(DESTINATIONSHEETNAME).getRange("A1").setValue("Last Published " + now);
This is not a tested code, let me know if any issues arises, I'll be happy to help you.
Thanks

Create template Google Sheet with script to rename from cell value

I am trying to create a Google Sheet template where a user can enter a value (Project URN) in a cell and run a script to save the template as a sheet, renamed with the Project URN.
I have created a test Google Sheet here https://docs.google.com/spreadsheets/d/1IPpQyYHl_TtNa1lGpmu4dlzwTFjOotV2OcnxFT84iUk/edit?usp=sharing
This sheet has the following script, but I cant get the renaming function to correctly work.
function saveAsSpreadsheet(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("0B7RrbZuJGLlha3NvM3ZqcTY3MDA");
DriveApp.getFileById(sheet.getId())
.(makeCopy(values = SpreadsheetApp.getActiveSheet()
.getRange(2, 2).getValues()), destFolder);
} //END function saveAsSpreadsheet
I did also find the following article but wasn't able to turn it to my use. However, the secret must be here somewhere! Rename worksheet to cell value keeping format
Kitten
You almost have it. Please try this:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get spreadsheet
var id = ss.getId(); // Get spreadsheet ID
var sstocopy = DriveApp.getFileById(id); //Get spreadsheet with DriveApp
var sheet = ss.getActiveSheet(); // Grab the sheet in order to find the name of the new spreadsheet to be created
var sheet_name = sheet.getRange("A1").getValue(); // Get the value, in this case: Project Urn
var folder = DriveApp.getFolderById("XXXX"); // Get the folder where the sheet needs to be placed.
sstocopy.makeCopy(sheet_name,folder); // Make the copy of the sheet in that folder.
}
Let me know if you have any questions.

copyto google apps script without "copy" in sheet name

I'm trying to use copyTo to duplicate an entire sheet from one Google Sheet to a brand new one. Everything works great however, the newly created Sheets all say "Copy" and then the Sheet name. Is there a way to remove the word Copy? Code is below.
function setupSheet()
{
var sources = SpreadsheetApp.openById('172teYmA4Bz61PscMQiTmpqWdvBUBDu_J2hR0m_8i_b8');
var allSheets = ['Display Case', 'Your Badges', 'Badge Directory', 'Activate Sheet'];
allSheets.forEach(function(each)
{
var thisSheet = SpreadsheetApp.getActive()
var sourcevalues = sources.getSheetByName(each).copyTo(thisSheet)
});
}
var sourcevalues =
sources.getSheetByName(each).copyTo(thisSheet).setName(each);