I'm trying to copy / transfer a sheet from one spreadsheet to another spreadsheet. I have tried various methods and .copyTo seems to be the best and most efficient way.
.copyTo works well but I'm struggling to send to a specific sheet...
Here is my code:
function TransferDataOut() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheetA = source.getSheets()[0]; //sheet source number
var destination = SpreadsheetApp.openById('the destination sheet');
var each = "Data_Incoming";
var ss = SpreadsheetApp.getActiveSpreadsheet();
sheetA.copyTo(destination); // I tried renaming .setName(each);
}
So if I only use sheetA.copyTo(destination); it simply creates a copy sheet, like Copy of the_souce_sheet_name.
If I try renaming to make it a specific name I will get error after running for the second time that the sheet already exists in destination spreadsheet.
What I really need to achieve is that the function from source spreadsheet copies data from the source sheet to always the same sheet in destination spreadsheet.
Perhaps .copyTo is not the right way to do it?
Any suggestions and code will help please!
The reason for receiving data on a exact sheet in the destination spreadsheet is because I have a trigger On change that executes another script to work with the new incoming data.
You want to overwrite the source sheet of Spreadsheet A to the destination sheet of Spreadsheet B.
You want to keep the sheet name of var each = "Data_Incoming".
If my understanding is correct, how about this answer? I would like to propose 2 samples. So please select one of them for your situation.
Sample script 1:
The flow of this sample script is as follows.
each sheet of Spreadsheet B is deleted.
Source sheet of Spreadsheet A is copied to the destination sheet of Spreadsheet B.
Sheet name of the copied sheet of Spreadsheet B is modified to each.
Modified script:
function TransferDataOut() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheetA = source.getSheets()[0]; //sheet source number
var destination = SpreadsheetApp.openById('the destination sheet');
var each = "Data_Incoming";
var destSheet = destination.getSheetByName(each);
if (destSheet) {
destination.deleteSheet(destSheet);
}
sheetA.copyTo(destination).setName(each);
}
Sample script 2:
The flow of this sample script is as follows.
Copy the source sheet of Spreadsheet A to Spreadsheet B.
If the sheet with the sheet name of each is not existing in Spreadsheet B, the copied sheet is renamed to each.
If the sheet with the sheet name of each is existing in Spreadsheet B, the source sheet is copied to the Spreadsheet B as Copy of ###.
each sheet is cleared.
All values, formulas and formats of the copied sheet are copied to each sheet.
Delete the copied sheet.
Modified script:
function TransferDataOut() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheetA = source.getSheets()[0]; //sheet source number
var destination = SpreadsheetApp.openById('the destination sheet');
var each = "Data_Incoming";
var copiedSheet = sheetA.copyTo(destination);
var destSheet = destination.getSheetByName(each);
if (destSheet) {
destSheet.clear();
var srcRange = copiedSheet.getDataRange();
srcRange.copyTo(destSheet.getRange(srcRange.getA1Notation()));
destination.deleteSheet(copiedSheet);
} else {
copiedSheet.setName(each);
}
}
Note:
In this sample script, each sheet of the Spreadsheet B (destination Spreadsheet) is deleted. So please be careful this.
So at first, as a test, I recommend to use a sample Spreadsheet.
References:
copyTo(spreadsheet) of Class Sheet
copyTo(destination) of Class Range
deleteSheet(sheet)
If I misunderstood your question and this was not the result you want, I apologize.
Added:
You want to run the script of destination Spreadsheet when the source values are copied to the destination Spreadsheet using the script in the source Spreadsheet.
The following sample script is for achieving above situation.
Script of destination Spreadsheet:
At first, the script of destination Spreadsheet is prepared.
Script:
function doGet() {
sample(); // This is the function that you want to run when the source values are copied.
return ContentService.createTextOutput();
}
After copy and paste above script to the script editor of destination Spreadsheet, please do the following flow.
Deploy Web Apps.
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
Select "Anyone, even anonymous" for "Who has access to the app:".
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Copy "Current web app URL:".
It's like https://script.google.com/macros/s/#####/exec.
Click "OK".
Script of source Spreadsheet:
As the next step, the script of source Spreadsheet is prepared as follows. In this sample, the sample 2 was used. I think that you can also use the sample 1.
Script:
function TransferDataOut() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheetA = source.getSheets()[0]; //sheet source number
var destination = SpreadsheetApp.openById('the destination sheet');
var each = "Data_Incoming";
var copiedSheet = sheetA.copyTo(destination);
var destSheet = destination.getSheetByName(each);
if (destSheet) {
destSheet.clear();
var srcRange = copiedSheet.getDataRange();
srcRange.copyTo(destSheet.getRange(srcRange.getA1Notation()));
destination.deleteSheet(copiedSheet);
} else {
copiedSheet.setName(each);
}
// Added
var url = "https://script.google.com/macros/s/###/exec"; // Please set the retrieved URL of Web Apps.
UrlFetchApp.fetch(url);
}
Note:
By above settings, when TransferDataOut() of the source Spreadsheet was run, doGet() of the destination Spreadsheet is run by UrlFetchApp.fetch(url).
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
Related
I am creating a copy of my google spreadsheet, and now want to close the current spreadsheet and open the one i created a copy. I know i can open it using the sheet id, but i dont know the sheet id yet because I want to achieve this using one macro!
current code -
function saveAsSpreadsheet(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("xxxxxxxxxxxxxxxxxxxxx");
DriveApp.getFileById(sheet.getId()).makeCopy("Test File", destFolder);
//want to open this copied file
}
By modified your code a little bit, then you can obtain the copy sheet Id with newsheet.getId() function:
function saveAsSpreadsheet(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var destFolder = DriveApp.getFolderById("xxxxxV6N-A4Z77f9OijHtAe2VhAU");
var newsheet = DriveApp.getFileById(sheet.getId()).makeCopy("Test File", destFolder);
Logger.log(newsheet.getId())
}
in my script , I am attempting the execute my code on a specific tab.
Here is my code snippet
function sendalert() {
var sheet = SpreadsheetApp.getActiveSheet();
My google sheet has 6 tabs, but I would like my script to run always on the tab named "Operator". How do I enforce this?
I believe your goal as follows.
You want to run the script for the sheet with the sheet name of Operator in the active Spreadsheet.
For this, how about this answer?
Modification points:
In order to access to the specific sheet using the sheet name, you can use getSheetByName(name).
When getActiveSheet() is used, the opened sheet in the browser is used. If the browser is not opened, the sheet of 1st tab is used.
Modified script:
When your script is modified, please modify as follows.
function sendalert() {
var sheetName = "Operator";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
// do something.
}
References:
getActiveSpreadsheet()
getSheetByName(name)
I do have two different google sheet, I need to copy say sheet Test from one to another using script, but getting error, any thought on this?
var source_sheet= "https://address of the otgoogle sheet tho be copied over")"
//here I'm on another google sheet, add a menu to copy the source from above
var ui = SpreadsheetApp.getUi();
//var ss = SpreadsheetApp.getActiveSpreadsheet();
var result = ui.prompt(
'Add New Sheet',
'Please enter Name',
ui.ButtonSet.OK);
var button = result.getSelectedButton();
var text = result.getResponseText();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.copyTo(link_to_src).setName(text);
Getting below error:
Exception: The parameters (String) don't match the method signature for SpreadsheetApp.Sheet.copyTo. (line xx, file "copy-rename")DetailsDismiss
Any help will be appreciated in advance..
You want to copy a sheet of the source Spreadsheet, which is not the active Spreadsheet to the active Spreadsheet, which run the script.
source_sheet is the URL of Spreadsheet like https://docs.google.com/spreadsheets/d/{spreadsheetId}/edit.
When you run the script, you want to input the sheet name in source Spreadsheet using a dialog and copy the sheet to the active Spreadsheet.
I could understand like above. If my understanding is correct, how about this modification?
Modified script
Please modify your script as follows. Before you run the script, please set the destination Spreadsheet URL to source_sheet.
From:
var sheet = ss.getActiveSheet();
sheet.copyTo(link_to_src).setName(text);
To:
var sourceSheet = SpreadsheetApp.openByUrl(source_sheet).getSheetByName(text);
if (sourceSheet) {
sourceSheet.copyTo(ss).setName(text).activate();
} else {
ui.alert(text + " sheet was not found.");
}
When you run the script, a dialog is opened. When a sheet name of the source Spreadsheet is inputted, the sheet is copied to the current active Spreadsheet, then, the copied sheet is activated.
If the sheet name which is not included in the source Spreadsheet is inputted, a dialog is opened.
References:
openByUrl(url)
copyTo(spreadsheet)
I'm trying to copy formatting only from a source sheet that is in a different workbook than the current sheet. Essentially, the source sheet format changes and I'd like to pull updates to the formatting into my destination sheet (which is the current sheet I would be working in). I'm using the following code, but I get "Cannot convert Spreadsheet to (class)" error" on the last line. Any insights?
var ss = SpreadsheetApp.openById("Source ID")
var source = ss
var destination = SpreadsheetApp.openById("Destination ID");
var range = source.getRange("N3:AE50");
range.copyFormatToRange(destination, 10, 27, 4, 50);
You want to copy the format from Spreadsheet A to Spreadsheet B. If my understanding is correct, how about this workaround? I think that there are several answers for your situation, so please think of this as one of them.
As tehhowch pointed out, copyFormatToRange() can be used for the same sheets in a Spreadsheet. For this situation, I understood that you want to use for between 2 Spreadsheets. In my workaround, I used the following flow.
Copy the source sheet of Spreadsheet with "Source ID" to Spreadsheet with "Destination ID".
Retrieve the range from the copied sheet as the source range.
Copy the source range to the destination sheet using copyFormatToRange().
Delete the copied sheet.
Sample script :
var sourceA1Notation = "N3:AE50";
var destinationA1Notation = "D10"; // row=4, col=10 This is the cell of upper left for putting the source range.
var source = SpreadsheetApp.openById("Source ID");
var destination = SpreadsheetApp.openById("Destination ID");
var sourceSheet = source.getSheets()[0]; // You can also use source.getSheetByName(name)
var destinationSheet = destination.getSheets()[0]; // You can also use source.getSheetByName(name)
var copiedsheet = sourceSheet.copyTo(destination);
var sourceRange = copiedsheet.getRange(sourceA1Notation);
var destinationRange = destinationSheet.getRange(destinationA1Notation);
sourceRange.copyFormatToRange(
destinationSheet,
destinationRange.getColumn(),
destinationRange.getColumn() + sourceRange.getNumColumns() - 1,
destinationRange.getRow(),
destinationRange.getRow() + sourceRange.getNumRows() - 1
);
destination.deleteSheet(copiedsheet);
Note :
When you use this, please input and confirm sourceA1Notation, destinationA1Notation, "Source ID" and "Destination ID".
destinationA1Notation is the cell of upper left for putting the source range.
In this sample script, each first sheet of "Source ID" and "Destination ID" is used. If you want to use other sheet, please modify this script.
References :
copyFormatToRange()
getSheets()
getSheetByName()
If I misunderstand what you want, I'm sorry.
I recently wrote my first Google Apps script that makes a copy of a spreadsheet (including all tabs within that spreadsheet) and places it into a specific folder in the user's Drive. The copy is renamed based on a cell value in the original spreadsheet. Here is my script, for reference:
function copyDocument() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Get current active spreadsheet.
var id = ss.getId(); // Get current active spreadsheet ID.
var sstocopy = DriveApp.getFileById(id); // Get spreadsheet with DriveApp.
var sheet = ss.getActiveSheet(); // Get current active sheet.
var sheet_name = sheet.getRange("B1").getValue(); // Get the value of cell B1, used to name the new spreadsheet.
var folder_name = sheet.getRange("C23").getValue(); // Get the target folder ID.
var folder = DriveApp.getFolderById(folder_name); // Get the ID of the folder where you will place a copy of the spreadsheet.
sstocopy.makeCopy(sheet_name,folder); // Make a copy of the spreadsheet in the destination folder.
}
This script works, but I have been asked to modify it because the script I wrote is copying over unnecessary tabs and data that is causing confusion to users.
The new script should make a copy of a specific range in a specific sheet, create a new spreadsheet, and paste that range into it. It should also name itself after a cell value in the range.
However, the only method I have come across that specifically copies a sheet into a new spreadsheet is copyTo(spreadsheet). However, the Google Apps Script Guide specifies that "the copied sheet will be named 'Copy of [original name]'" by default.
I want to be able to rename the copied sheet after a specific cell. My question is, can I use copyTo(spreadsheet) and give the new spreadsheet a custom name, based on a cell?
Thanks!
You will need to get the data from the specific sheet to copy out to a variable of using:
var sourceSheet = ss.getSheetByName("Sheet1");
var sourceData = sourceSheet.getDataRange().getValues();
var originalRangeNotation = sourceSheet.getDataRange().getA1Notation();
Then you need to create a new, empty file and make a sheet with the same name
var ssNew = SpreadsheetApp.create("My New File Name");
ssNew.insertSheet('My New Sheet');
Then add the contents from the saved data to the new file. Since the insertSheet makes the new sheet the active one, we use:
var sheetNew = ssNew.getActiveSheet();
var rangeNew = sheet.getRange(originalRangeNotation);
range.setValues(sourceData);
Thanks. I ended up using this in place of sstocopy.makeCopy()
folder.addFile()
new_sheet.getActiveSheet().getRange("X:Y").setValues(sheet.getRange("X:Y").getValues())
DriveApp.getRootFolder().removeFile(temp)