How can copy specifics sheet to another spreadsheet using google script - google-apps-script

Situation:
I have a spreadsheet with 10 worksheets and 15 users logging in and modifying it. I want to copy just 6 sheet from other spreadsheet.
Script Function Needed:
The script should be copy sheet to another spreadsheet specific.
1)
Source = XXXXXX
I want to copy from Source only the sheets1,2,3,4,5,6,7,8 to target.
Target = YYYYY
Note: The Target already have the sheet1,2,3,4,5,6,7,8. I needs update that Target spreadsheet because I use that to make Reports. I can not use the surce because this report are confidential.
2)
The script needs to be run from the target.
Problem:
I read a lot of forum but anyone provide a generic script about "How to Copy Sheets to anothers Sheet". All those script are very complex an I'm newbe with this.
Test Case:
N/A
I thinks is a simple copy of sheet from one spreadsheet to another but I needs to do this in oneshot actually I am doing it manually but I have issue the system change the sheet name to Copy of XXXXX but my Reports are configured to use a specific name, that why I needs make this possible. I thinks this script will help to many people.
Thanks in Advance.
EDIT: 14/06/2013
Hi,
Please could you help me to tunning this script to work more effective.
function UpdateData() {
var source = SpreadsheetApp.openById('YYYYYY');
var sheet8 = source.getSheets()[8];
var sheet7 = source.getSheets()[7];
var sheet6 = source.getSheets()[6];
var sheet5 = source.getSheets()[5];
var sheet4 = source.getSheets()[4];
var sheet3 = source.getSheets()[3];
var sheet2 = source.getSheets()[2];
var sheet1 = source.getSheets()[1];
var destination = SpreadsheetApp.openById('ZZZZZZ');
sheet8.copyTo(destination).setName('Sheet8');
sheet7.copyTo(destination).setName('Sheet7');
Utilities.sleep(100);
sheet6.copyTo(destination).setName('Sheet6');
sheet5.copyTo(destination).setName('Sheet5');
Utilities.sleep(100);
sheet4.copyTo(destination).setName('Shee4');
sheet3.copyTo(destination).setName('Shee3');
Utilities.sleep(100);
sheet2.copyTo(destination).setName('Shee2');
sheet1.copyTo(destination).setName('Shee1');
SpreadsheetApp.flush();
}

just look into the docs: copyTo(spreadsheet), from the description:
Copies the sheet to another spreadsheet. The destination spreadsheet
can be the source. The new spreadsheet will have the name "Copy of
[original spreadsheet name]"
The method returs the copied sheet so you can rename it:
sourceSheet.copyTo(targetSpreadSheet).setName('somename');
I hope, you know how to write a loop in JS ...

Related

Google sheets appscript to copy tabs to new sheets

I have a google sheet with around 190 tabs on that i need to split into 190 different files
The files need to be named the same as the tab, the contents of the tab need to be copied as values but i also need to bring the formatting accross (just not the formulas).
I have looked around, and through a combination of previous questions and answers plus using the function list help have formed the following code. It actually works for the first few tabs but then throws up an error about being unable to delete the only sheet.
function copySheetsToSS() {
var ss = SpreadsheetApp.getActive();
for(var n in ss.getSheets()){
var sheet = ss.getSheets()[n];// look at every sheet in spreadsheet
var name = sheet.getName();//get name
if(name != 'master' && name != 'test'){ // exclude some names
var alreadyExist = DriveApp.getFilesByName(name);// check if already there
while(alreadyExist.hasNext()){
alreadyExist.next().setTrashed(true);// delete all files with this name
}
var copy = SpreadsheetApp.create(name);// create the copy
sheet.copyTo(copy);
copy.deleteSheet(copy.getSheets()[0]);// remove original "Sheet1"
copy.getSheets()[0].setName(name);// rename first sheet to same name as SS
var target_sheet = copy.getSheetByName(name);
var source_range = sheet.getRange("A1:M50");
var target_range = target_sheet.getRange("A1:M50");
var values = source_range.getValues();
target_range.setValues(values);
}
}
}
I am hoping someone can tell me what i have done wrong as I cannot figure it out at this point. I am also open to better solutions though please be aware I am very much a beginner on google appscript, nothing too complex please.
thankyou
In principle your script correctly adds a new sheet to the new spreadsheet before removing the preexisting one
However, mind that calls to service such as SpreadsheetApp are asynchronous.
And this becomes the more noticeable, the longer your script runs.
In your case it apparently leads to behavior that the only sheet is being deleted before the new sheet is being created.
To avoid this, you can force the execution to be synchronous by implementing calls to SpreadsheetApp.flush().
This will ensure that the old sheet won't be deleted before the new one gets inserted.
Sample:
copy.deleteSheet(copy.getSheets()[0]);// remove original "Sheet1"
SpreadsheetApp.flush();
copy.getSheets()[0].setName(name);
You might want to introduce call toflush()` also at other positions where it is important for the code to run synchronously.

Script to save full Google Spreadsheet to folder

I want to create a function to save a spreadsheet to a folder.
I'm almost there, I think I just need to adjust the synthax of the createFile class.
Here is my code:
const spreadsheet2 = SpreadsheetApp.getActiveSpreadsheet();
var folder2 = DriveApp.getFoldersById("my_folder_id").next();
var filename2 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("B97").getValue();
folder2.createFile([I think here is my missing command].setName(filename2));
Could someone finish it?
You want to copy the active Spreadsheet to the specific folder.
You want to use the filename from getActiveSheet().getRange("B97").getValue().
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
At DriveApp.getFoldersById("my_folder_id").next(), there is no method of getFoldersById. When you want to use the folder ID, please use DriveApp.getFolderById(folderId).
Unfortunately, the Spreadsheet cannot be directly created with createFile(). In your case, in order to copy the active Spreadsheet, you can use makeCopy().
When above points are reflected to your script, it becomes as follows.
Modified script:
var folderId = "###"; // Please set the folder ID you want to put the copied Spreadsheet.
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var filename2 = spreadsheet.getActiveSheet().getRange("B97").getValue();
var folder = DriveApp.getFolderById(folderId);
DriveApp.getFileById(spreadsheet.getId()).makeCopy(filename2, folder);
References:
getFolderById()
makeCopy()

Insert new row at top of sheet based on new rows in another tab

I have a Google sheet with a listing of job candidates in one tab (Primary candidates sheet). What I would like to do is paste a daily export of candidates into another tab and have new candidates from the latest export inserted up top of the primary candidates sheet.
I've tried to search this methodology online which typically leads to success after some research. However, I can't seem to find any documentation on macros, scripts, or formulas which could accomplish this.
Wanted to see if anyone had any resources for additional research.
You can use below code to copy data from source sheet into top of destination sheet. Enter sheet names accordingly. Save. From script editor menu, Run > Function > Test, to test. It'll insert new rows in destination sheet and source sheet data will stay as is.
function test() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheetByName('source sheet name here'); // change here
var des = ss.getSheetByName('destination sheet name here'); // change here
var sv = source
.getDataRange()
.getValues();
sv.shift();
des.insertRowsAfter(1, sv.length);
des.getRange(2, 1, sv.length, source.getLastColumn()).setValues(sv);
}

Programmatically delete a script

I was wondering if someone could offer me some advice.
I have a master spreadsheet, acting as a template. I have written a script which can be run from the menu (using addToUi command), which makes a copy of template spreadsheet.
The problem is that the script gets copied into the new spreadsheet also which I don't want.
Could anyone suggest a possible way around this please?
I did think a possible way was to get the script to open the copied template and delete the script but not sure if this is possible.
Here is the function which does the copying....
function createCopy() {
var myValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("B8").getValue();
var destinationFolder = DriveApp.getFolderById("xxxxxxxxxxxxxxxx");
DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).makeCopy(myValue,destinationFolder);
}
(Cell reference B8 holds the value of what I called the copied spreadsheet).
Rayden, I use a function like that to just copy one sheet to a new spreadsheet and it doesn't drag the script with it. gDrive is the id for the Spreadsheet, tabName the individual sheet you want copied, Filename the name of the copy and destination the destination directory.
//******************************************************************************
//- This function takes a tab and makes it its own file
function tabToSheet(gDrive,tabName,fileName,destination){
var sh = SpreadsheetApp.openById(gDrive);
var ss = sh.getSheetByName(tabName);
//create a new document in the location given
var newSheet = SpreadsheetApp.create("TEMPDELETEME");
//copy the tab from current document to new document
ss.copyTo(newSheet);
var id = newSheet.getId();
newSheet.deleteSheet(newSheet.getSheetByName("Sheet1"));
os = newSheet.getSheets()[0];
os.setName(tabName);
var file = DriveApp.getFileById(id);
var folder = DriveApp.getFolderById(destination);
var finalId = file.makeCopy(fileName, folder).getId();
file.setTrashed(true);
return finalId;
}//*****************************************************************************
The difference is that i'm making a new sheet, then copying the tab rather than copying the entire file. You could add another tab and remove the variables if you want to copy multiple tabs.
I was having trouble implementing J.G.'s approach of moving individual sheets, so the approach I took was to add a conditional in front of the script to only run if the spreadsheet id was equal to the id of the original spreadsheet. My use case was trying to suppress a custom menu on the original workbook from reappearing on the copy, so it worked for that.
var bookId = spreadsheet.getId();
if (bookId === 'original spreadsheet id') {
*Function*
}

How to duplicate a sheet on a user-selected target spreadsheet and copy data

I’m very new to Google Apps Script, and I’m having trouble trying to accomplish my goal.
I have a Google Sheets Workbook that allows users to:
Select a name from a drop down (each name has a unique/individual
google workbook URL associated with it)
Type in a desired spreadsheet name
Press a “Push Sheet” button
Once the user presses the button, I’m trying to accomplish the following things:
Duplicate the sheet 'Template - Do Not Modify’ that already exists on target workbook (the URL associated with the selected name)
Rename the duplicated sheet to the desired spreadsheet name
Copy the range A7:D150 from the sheet “Tracker” on the original workbook to the range A7:D150 newly created sheet on the target workbook
The original sheet is set up to have the user authorize the workbook connection prior to running the script.
Here's my code:
function cloneGoogleSheet() {
var sheet = SpreadsheetApp.getActiveSheet();
var name = sheet.getRange("B10").getValue();
var url = sheet.getRange("f5").getValue();
var tss = SpreadsheetApp.openByUrl(url);
tss.setActiveSheet(tss.getSheetByName('Template - Do Not Modify'));
tss.duplicateActiveSheet();
var activesheet = tss.getActiveSheet();
activesheet.setName(name);
}
My issues are:
It doesn't seem like utilizing ActiveSheets is a safe way to do all of this and that there's a better way.
When attempting to use the URL variable (the script runs fine with a hardcoded URL value), I get an invalid argument: URL error. The cell F5 updates to a new URL based on what name is selected from the drop down, using a lookup which references names with unique URLs:
=lookup(B4,
{P71,P72,P73,P74,P75,P76,P77},
{Q71,Q72,Q73,Q74,Q75,Q76,Q77}
)
Given the fact that I'm using all these ActiveSheet variables, I'm not sure how to get back to my original sheet to copy the ranges.
I would very much appreciate someone showing me the correct way to do this. Thanks!
Have you tried using "getSheetByName"?
Try Armit Agarwal's tutorial on Duplicate a Sheet in Google Spreadsheets:
function cloneGoogleSheet() {
var name = "labnol";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Template').copyTo(ss);
/* Before cloning the sheet, delete any previous copy */
var old = ss.getSheetByName(name);
if (old) ss.deleteSheet(old); // or old.setName(new Name);
SpreadsheetApp.flush(); // Utilities.sleep(2000);
sheet.setName(company);
/* Make the new sheet active */
ss.setActiveSheet(sheet);
}