App script - Create copy of single tab/sheet - javascript

Im trying to .makecopy of a single tab or sheet from a spreadsheet with multiple tabs, Im able to make a copy of the entire sheet however this includes information the end user does not need to see.
I've seen some threads about creating a new spreadsheet within apps script then coping over the detail although formatting gets messy, I know there is a way to fix this but i'd like to know if there is a method as simple as the one i use currently to copy an entire sheet.
//Written like a true noob.
function Createcopy() {
//Base
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Review')
var date = sheet.getRange(1,3).getValue(); // Probably wont need.
//Folder detail
var folderid = '1iEILmAp3JiOTiPjFbDhv0bAfgu6AWhtd'
var Folder = "https://drive.google.com/drive/folders/"+folderid
Logger.log(folderid)
//Create copy
var title = sheet.getRange(1,4).getValue();
Logger.log(title)
var filename = title
var destFolder = DriveApp.getFolderById(folderid);
var createdcopy = DriveApp.getFileById(ss.getId()).makeCopy(filename, destFolder);
var url = createdcopy.getUrl()
Logger.log(url)
}

I believe your goal is as follows.
You want to copy the specific sheet in a Google Spreadsheet to a new Google Spreadsheet.
You want to put the new Spreadsheet in the specific folder.
You want to retrieve the URL of the new Spreadsheet.
Modification points:
As you say, your script copies the whole Spreadsheet.
In this case, I would like to propose the following flow.
Retrieve source sheet.
Copy the source sheet to a new Spreadsheet and remove the default empty sheet.
Move a new Spreadsheet to the destination folder.
Retrieve the URL of a new Spreadsheet.
When this flow is reflected in your script, it becomes as follows.
Modified script:
function Createcopy() {
var sheetName = 'Review'; // Please set the source sheet name.
var folderId = '###'; // Please set the destination folder ID.
// 1. Retrieve source sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var title = sheet.getRange(1, 4).getValue(); // New Spreadsheet title. This is from your script.
// 2. Copy source sheet to a new Spreadsheet and remove the default empty sheet.
var newSS = SpreadsheetApp.create(title);
sheet.copyTo(newSS).setName(sheetName);
newSS.deleteSheet(newSS.getSheets()[0]);
// 3. Move a new Spreadsheet to the destination folder.
var dstFolder = DriveApp.getFolderById(folderId);
DriveApp.getFileById(newSS.getId()).moveTo(dstFolder);
// 4. Retrieve URL of a new Spreadsheet.
var url = newSS.getUrl();
Logger.log(url)
}
When this script is run, the source sheet is copied to a new Spreadsheet. And, at a new Spreadsheet, the default empty sheet is removed. By this, a Spreadsheet including the specific sheet is obtained.
Note:
In this case, if the source sheet includes the formulas for loading the values from another sheet, an error occurs. Please be careful about this. And also, for example, when the source sheet includes the custom function, I think that the following script might be able to be used.
function Createcopy() {
var sheetName = 'Review'; // Please set the source sheet name.
var folderId = '###'; // Please set the destination folder ID.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var title = sheet.getRange(1, 4).getValue(); // New Spreadsheet title. This is from your script.
var dstFolder = DriveApp.getFolderById(folderId);
var newSSFile = DriveApp.getFileById(ss.getId()).makeCopy(title, dstFolder);
var newSS = SpreadsheetApp.open(newSSFile);
newSS.getSheets().forEach(s => {
if (s.getSheetName() != sheetName) newSS.deleteSheet(s);
});
var url = newSS.getUrl();
Logger.log(url)
}
References:
create(name)
copyTo(spreadsheet) of Class Sheet of Class SpreadsheetApp

Related

Google apps script to duplicate script in a different folder giving type error when I try to access new sheet id ()

I am trying to run a google apps script that copies the current script to another folder but for some reason getId() after the copy function duplicateactivesheet is not allowing me to access the new sheets id.
TypeError: newSheet.getId is not a function
copySheetToFolder # Code.gs:29
I get a Type error after running:
function copySheetToFolder(folderId) {
// Get the sheet to be copied
//var sheet = SpreadsheetApp.getActiveSheet();
sheet = SpreadsheetApp.getActiveSpreadsheet();
// Make a copy of the sheet
var newSheet = sheet.duplicateActiveSheet();
// Get the ID of the new sheet
var newSheetId = newSheet.getId();
// Get the folder where the sheet will be copied
var folder = DriveApp.getFolderById(folderId);
// Add the sheet to the folder
folder.addFile(DriveApp.getFileById(newSheetId));
}
From your provided official document, duplicateActiveSheet() is the method of Class Spreadsheet. But, in your script, sheet of var sheet = SpreadsheetApp.getActiveSheet() is Class Sheet. I think that this is the reason for your current issue of TypeError: SpreadsheetApp.getActiveSheet(...).duplicateActiveSheet is not a function.
But, from a google apps script that copies the current script to another folder, I thought that you might have wanted to copy the active spreadsheet to the specific folder. If my understanding is correct, how about the following modification?
Modified script:
function copySheetToFolder(folderId) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
DriveApp.getFileById(ss.getId()).makeCopy(DriveApp.getFolderById(folderId));
}
By this modification, the active Spreadsheet is copied to the specific folder of folderId.
If you want to give a new title of Spreadsheet, please use DriveApp.getFileById(ss.getId()).makeCopy("new name", DriveApp.getFolderById(folderId)).
Note:
If you want to use duplicateActiveSheet(), please use the following modification.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var newSheet = ss.duplicateActiveSheet();
References:
duplicateActiveSheet()
getFileById(id)
makeCopy(destination)
Added:
Now, I noticed that you updated your question after I posted an answer. About your new issue of TypeError: newSheet.getId is not a function, I think that the reason of your new issue is due to that you are using the sheet ID as the spreadsheet ID. If you want to move the Spreadsheet to the specific folder after you copied the active sheet, please modify as follows.
Modified script:
function copySheetToFolder(folderId) {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
sheet.duplicateActiveSheet();
var ssId = sheet.getId();
var folder = DriveApp.getFolderById(folderId);
DriveApp.getFileById(ssId).moveTo(folder);
}
From your showing script, in this modification, the active sheet is copied and the active Spreasheet is moved to the specific folder.
In the current stage, addFile of Class Folder has been deprecated. Please be careful about this. Ref In this modification, moveTo is used. Ref

Running Macro on Multiple Google Sheets Workbooks

I have a large directory of workbooks that I need to change the parameters of a named range. I have recorded a Macro that can do this and I'm sure there's a quick way to apply?
I have a Tab in a directory workbook called 'Planner Fixes' & I have a list of Sheet ID's to send the amendment too.
The Macro is as below:
function ElementsEdit() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').activate();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('API BootstrapStatic'), true);
spreadsheet.getRange('A2:BK514').activate();
spreadsheet.setNamedRange('Elements', spreadsheet.getRange('A2:BK1000'));
spreadsheet.getActiveSheet().hideSheet();
};
I know that the line var spreadsheet = SpreadsheetApp.getActive(); needs to change to look for the spreadsheet ID and 'open' that?
I'm very new to scripts and have generally only used ones I have found online but I can't seem to find anything to do this at all.
If you have multiple workbooks, and if you know the id of each of them, try
var spreadsheet = SpreadsheetApp.openById(YOUR_SPREADSHEET_ID);
for each
You can loop through a list of id
const ids = [
'1T7ixa-JGLgh8oxxxxxxxxxo4UzbivflUlwL9zLGVkgg',
'16uEeVNEBzBbGVTgKa98yyyyyyyyyyyy6mU-yKIZ0fKM',
'1d3ZHizzzzzzzzzzzzzzzzzzzLkmM4bFHyDn8RFtAlkk'
]
function myFunction() {
ids.forEach((id, i) => {
var spreadsheet = SpreadsheetApp.openById(id)
// your script here
})
}

Google Script - Adding images in document & removing copied files

I'm passing information from Google Sheets to a Document via Google Apps Script. All the information transfers with two exceptions...
The link of the picture shows rather than the image. How can I insert the image rather than the link?
In the folder it saves to, I get 2 versions of the document. One with the name I want, and another named 'Copy of Template'. I don't want the copy of the template, how can I either not create it, or delete it in the script?
Any help would be greatly appreciated.
function myFunction(e) {
var timestamp = e.values[0];
var studentName = e.values[1];
var firstName = e.values[2];
var studentNumber = e.values[3];
var dateOfBirth = e.values[4];
var studentImage = e.values[5];
var file = DriveApp.getFileById('fileId');
var folder = DriveApp.getFolderById('folderId')
var copy = file.makeCopy(studentName, folder);
var doc = DocumentApp.openById(copy.getId());
var body = doc.getBody();
body.replaceText('{{Time}}', timestamp);
body.replaceText('{{Name}}', studentName);
body.replaceText('{{Preferred Name}}', firstName);
body.replaceText('{{Student Number}}', studentNumber);
body.replaceText('{{DOB}}', dateOfBirth);
body.replaceText('{{Image}}', studentImage);
doc.saveAndClose();
}
The expected output is a document with relevant information, an image of the student, and only 1 version of the document in the folder.
I am unsure of why your code creates an extra copy of your file. This might be due to something else.
However, to change "{{image}}" to an image from an URL you can do this:
body.findText('{{Image}}').getElement().asParagraph()
.setText("") //Clears text
.appendInlineImage(UrlFetchApp.fetch(studentImage).getBlob()); //Adds image element from URL

After selecting a range on a Google Sheet, how do I paste the selection into a Google Doc?

I'm trying to create a macro on a Google Sheet that will select a range from the sheet and then paste the selected contents into to a Google Doc. So far I have the code to select the range:
function CopyToDoc() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A4:B13').activate();
}
Once I select the range, how do I paste it into a google doc?
Well to achieve what you are saying I would do this.
function sheetToDoc(){
var app = SpreadsheetApp;
var as = app.getActiveSpreadsheet();
var sh = as.getSheets()[0];
var temp = sh.getRange("A1:A20").getValues();
var doc = DocumentApp.openById("DocID").getBody().appendTable(temp);
}
Use AppendTable() to add the information to your document in a table and appendParagraph() if you want to add the information to your document as plain text. Make test for you to know how the information will be added to your document.
I hope this helps. Greetings

Import range script timeout

SO of late my importrange formulas have been collapsing so I decided to give the script version a try. I have a google script I got. The logic flow makes a lot of sense but when executing, it just runs endlessly without any output. Finally, it gives a timeout error at the end. I tried adding SpreadsheeetApp.flush() but it didn't work either. Here is the script below. Any assistance would be greatly appreciated.
function cloneGoogleSheet() {
// source doc
var sss = SpreadsheetApp.openById('ssA');
// source sheet
var ss = sss.getSheetByName('Source spreadsheet');
// Get full range of data
var SRange = ss.getDataRange();
// get A1 notation identifying the range
var A1Range = SRange.getA1Notation();
// get the data values in range
var SData = SRange.getValues();
// target spreadsheet
var tss = SpreadsheetApp.openById('ssB');
// target sheet
var ts = tss.getSheetByName('Target Spreadsheet');
// Clear the Google Sheet before copy
ts.clear({contentsOnly: true});
// set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
};

Categories