I have code which does the following:
Collects values from first sheet "OTW Sheet"
Opens another existing sheet by Id - "Invoice"
Sets values in "Invoice" as copied from "OTW Sheet"
Creates a new spreadsheet in the Drive App and copies "Invoice" to new Spreadsheet.
This all works well but the next step is to delete the sheet called "Sheet1" in the newly created Spreadsheet. This part I can't get to work. No errors appear, it just fails to delete the sheet.
Code is as follows:
function myFunction() {
var orderSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("OTW Sheet");
var row = OrderSheet.getLastRow();
var values1 = OrderSheet.getRange(row, 5).getValue();
var cost1 = OrderSheet.getRange(1, 16).getValue();
var invoice = SpreadsheetApp.openById("19wv72wCNsPV6_hK8XCRcMBkfzEEU1IrJB6scuPz2Vfo");
invoice.getSheetByName("BLANK");
var newsheet = Invoice.getActiveSheet();
newsheet.getRange(17, 7).setValue(cost1);
newsheet.getRange(1, 15).setValue(values1);
var newSS = SpreadsheetApp.create('OTW Invoice');
newsheet.copyTo(NewSS).setName('OTW Invoice ' + cost1).getSheetId();
var folder = DriveApp.getFoldersByName("TEST Invoices").next();
var copyFile = DriveApp.getFileById(newSS.getId());
folder.addFile(CopyFile);
newSS.getId();
SpreadsheetApp.openById(NewSS).getSheetByName("Sheet1").deleteSheet();
}
Replace
NewSS.getId();
SpreadsheetApp.openById(NewSS).getSheetByName("Sheet1").deleteSheet();
by
NewSS.deleteSheet(NewSS.getSheetByName("Sheet1"));
Reference
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#deletesheetsheet
Deleting A Sheet of a newly created spreadsheet
This works:
function myFunction() {
const ss = SpreadsheetApp.openById("ssid");
const sh = ss.getActiveSheet();
const nss = SpreadsheetApp.create('OTW Invoice');
sh.copyTo(nss).setName('OTW Invoice ' + ' Copy');
const fldr = DriveApp.getFoldersByName("TestFolder").next();//assume only one
const file = DriveApp.getFileById(nss.getId());
fldr.addFile(file);//move nss to a subfolder
nss.deleteSheet(nss.getSheetByName("Sheet1"));
}
Related
I am working on a function where I copy a template sheet to another sheet.
Right now I have a demo where I hardcode the name of the template sheet that I want to add.
function AddFeature(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Defines Sheet that uses the function
var sheet = ss.getSheetByName("Client Balance");
//Get the template sheet
var templateSheet = ss.getSheetByName("Summary Sheet");
var totalrow = sheet.getLastRow();
for (var r = 2; r <= totalrow; r++){
var url = sheet.getRange(r,2).getValue();
var destSheet = SpreadsheetApp.openByUrl(url);
//Paste the template sheet to destination spreadsheet
templateSheet.copyTo(destSheet);
destSheet.getSheetByName("Copy of Summary Sheet").activate();
destSheet.moveActiveSheet(1); //Move the pasted template sheet to sheet at Index
destSheet.getSheetByName("Copy of Summary Sheet").setName("Summary Sheet"); //Rename the sheet
}
}
I want my script to draw the name of the sheet it needs to copy from a cell. I tried using this:
var fname = sheet.getRange(1,3).getValue;
var cname = sheet.getRange(1,4).getValue;
Where I would replace all "Summary Sheet" with : fname
and all "Copy of" with: cname
and they come from my sheet that looks like this:
Minimal reproductive example:
function AddFeature(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Defines Sheet that uses the function
var sheet = ss.getSheetByName("Client Balance");
//Defines which cells have the sheet name and "Copy of" sheet name
var fname = sheet.getRange(1,3).getValue;
var cname = sheet.getRange(1,4).getValue;
//Get the template sheet
var templateSheet = ss.getSheetByName(cname);
var totalrow = sheet.getLastRow();
for (var r = 2; r <= totalrow; r++){
var url = sheet.getRange(r,2).getValue();
var destSheet = SpreadsheetApp.openByUrl(url);
//Paste the template sheet to destination spreadsheet
templateSheet.copyTo(destSheet);
destSheet.getSheetByName(cname).activate();
destSheet.moveActiveSheet(1); //Move the pasted template sheet to sheet at Index
destSheet.getSheetByName(cname).setName(fname); //Rename the sheet
}
}
The statements that get the sheet names try to fetch the values from cells C1 and D1. Your screenshot suggests that the values should instead be fetched from cells C2 and D2. Try this:
var fname = sheet.getRange('C2').getValue();
var cname = sheet.getRange('D2').getValue();
With this script ( Generate new spreadsheet from a selected row based on template ) I can generate a new spreadsheet (and so not a tab), based on a template tab (in this case, the tab "xxx") only when I select a specific row and rename this Spreadsheet as the value in the cell in column B for that corresponding row.
Now, I would copy the value of the cell A2 from the source spreadsheet into the tab "xxx" in the cell A3.
How to do that?
function onOpen() {
SpreadsheetApp.getUi().createMenu('Genera Scheda')
.addItem('Genera Scheda', 'createSpreadsheet')
.addToUi()}
function createSpreadsheet() {
var ss = SpreadsheetApp.getActive();
// the following line means that the function will search for the spreadsheet name in the active sheet, no matter which one it is
var sheet = ss.getActiveSheet();
//the selected row
var row = sheet.getActiveCell().getRow();
// column 2 corresponds to "B"
var name = sheet.getRange(row, 2).getValue();
var templateSheet1 = ss.getSheetByName('xxx');
var templateSheet2 = ss.getSheetByName('xxx2');
var newSpreadsheet = SpreadsheetApp.create(name);
var fileId = newSpreadsheet.getId();
var file = DriveApp.getFileById(fileId);
var folderId ="-----";
var folder = DriveApp.getFolderById(folderId);
templateSheet1.copyTo(newSpreadsheet).setName("Scheda");
templateSheet2.copyTo(newSpreadsheet).setName("Import")
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Foglio1"));
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
}
To copy individual cell values between tabs and spreadsheets, a good solution is to use getValue() and setValue()
This methods must be applied to range objects (that is the cells).
Sample:
...
// define sheet either as the active sheet or specify it with sheet = ss.getSheetByName("XXX");
var myValue = sheet.getRange("A2").getValue();
newSpreadsheet.getSheetByName("xxx").getRange("A3").setValue(myValue);
...
Note that if you want to get / set values of more than one cell simulataneously, you need to use getValues() and setValues() instead.
UPDATE
Full code based on your situation:
function onOpen() {
SpreadsheetApp.getUi().createMenu('Genera Scheda')
.addItem('Genera Scheda', 'createSpreadsheet')
.addToUi()}
function createSpreadsheet() {
var ss = SpreadsheetApp.getActive();
// the following line means that the function will search for the spreadsheet name in the active sheet, no matter which one it is
var sheet = ss.getActiveSheet();
//the selected row
var row = sheet.getActiveCell().getRow();
// column 2 corresponds to "B"
var name = sheet.getRange(row, 2).getValue();
var templateSheet1 = ss.getSheetByName('xxx');
var templateSheet2 = ss.getSheetByName('xxx2');
var newSpreadsheet = SpreadsheetApp.create(name);
var fileId = newSpreadsheet.getId();
var file = DriveApp.getFileById(fileId);
var folderId ="-----";
var folder = DriveApp.getFolderById(folderId);
templateSheet1.copyTo(newSpreadsheet).setName("Scheda");
templateSheet2.copyTo(newSpreadsheet).setName("Import")
var myValue = sheet.getRange("A2").getValue();
newSpreadsheet.getSheetByName("Scheda").getRange("A3").setValue(myValue);
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Foglio1"));
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
}
My code automatically creates a user-specific google sheet when a new entry on a row is added. I want it to then copy and paste the URL of this new sheet into a tracking sheet within a different google sheet
I've tried opening the sheet and copying the link, and just getting the URL and copying. It does log the URL to the lgoger, but no idea how to get it to log it on the actual sheet
function createNewSS() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName('Active Campaign');
var row = ss.getLastRow();
var name = sourceSheet.getRange(row,4).getValue ()
var ssNew = SpreadsheetApp.create(name);
var insertLink = ssNew.getUrl()
Logger.log(ssNew.getUrl());
Solved
function createNewSS() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName('Active Campaign');
var row = ss.getLastRow();
var name = sourceSheet.getRange(row,4).getValue ();
var ssNew = SpreadsheetApp.create(name).getUrl();
sourceSheet.getRange(row,5).setValue(ssNew);
In Google Apps Script, Im using the script below to create a pdf and send as an email.
The problem is that when it creates the new sheet and copies across, the formulas are copied. The emailed PDF than shows a REF error.
I need to copy the Value and Format.
Thanks
function exportPDF() {
var originalSpreadsheet = SpreadsheetApp.getActive();
var message = "Please see attached";
var projectname = originalSpreadsheet.getRange("a2:c2").getValues();
var period = originalSpreadsheet.getRange("B24:c24").getValues();
var subject = projectname + " - Daily Control Totals - " + period;
var contacts = originalSpreadsheet.getSheetByName("Contacts");
var numRows = contacts.getLastRow();
var emailTo = contacts.getRange(2, 2, numRows, 1).getValues();
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Daily Totals.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);}
Currently, if you have references to other sheets in the sheet you are copying, after copying you will get REF errors, which makes sense as the data is no longer where it should be.
To avoid that when we can use Range's copyTo(Range, Object); method. However, this method can only be used within a single spreadsheet, so we need to create a temporary sheet that will store our values then copy the sheet to a new spreadsheet to send in an email:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var newSS = SpreadsheetApp.create("Spreadsheet to export");
var temp = ss.duplicateActiveSheet(); //create temp sheet that lets us copy the values
range = temp.getDataRange();
range.copyTo(range, {contentsOnly: true}); //copy the values
temp.copyTo(newSS); //copy the values to a new spreadsheet
ss.deleteSheet(temp); //delete our temp sheet.
Updated: So your code would look something like this:
function exportPDF() {
var originalSpreadsheet = SpreadsheetApp.getActive();
var message = "Please see attached";
var projectname = originalSpreadsheet.getRange("a2:c2").getValues();
var period = originalSpreadsheet.getRange("B24:c24").getValues();
var subject = projectname + " - Daily Control Totals - " + period;
var contacts = originalSpreadsheet.getSheetByName("Contacts");
var numRows = contacts.getLastRow();
var emailTo = contacts.getRange(2, 2, numRows, 1).getValues();
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
sheet = originalSpreadsheet.getActiveSheet();
var temp = originalSpreadsheet.duplicateActiveSheet(); //create temp sheet that lets us copy the values
range = temp.getDataRange();
range.copyTo(range, {contentsOnly: true}); //copy the values
temp.copyTo(newSpreadsheet); //copy the values to a new spreadsheet
ss.deleteSheet(temp); //delete our temp sheet.
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Daily Totals.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
}
Script would run in the source workbook.
function CopyDataToNewFile() {
var sss = SpreadsheetApp.openById('1yeS6_qhURUYHVkImLNMjdGUeMWhPDwQKdLNgpygiwG4'); // sss = source spreadsheet
var ss = sss.getSheetByName('Sheet1'); // ss = source sheet
//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();
var tss = SpreadsheetApp.openById('1KQBsMJ0vgBQwkM89d166RPyVahIZY3DRSOWVCB4zapE'); // tss = target spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var first = ss.getSheetByName('Sheet1');
sheet.clear({ formatOnly: false, contentsOnly: true });
var tss = SpreadsheetApp.openById('1KQBsMJ0vgBQwkM89d166RPyVahIZY3DRSOWVCB4zapE');
var ts = tss.getSheetByName('Sheet1'); // ts = target sheet
//set the target range to the values of the source data
ts.getRange(A1Range).setValues(SData);
}
Would set to trigger on form submit. Would copy the data from a sheet in one workbook to a sheet in another workbook. Format of both sheets will be same AND must remain unaltered. Row & column count/size will be same on each sheet.
Here a code that will go through all the sheet of your source workbook and copy data in the current workbook. Sheet name will be the same of source spreadsheet and only data are copied.
EDIT : Code changed to not copy but import data from spreadsheet to a dest spreadsheet where we assume that the sheet is already created. If sheet does not exist we create it.
function importWorkBook(){
var idSource = "IdOfTheSheetSource";
var sheets = SpreadsheetApp.openById(idSource).getSheets();
var current = SpreadsheetApp.getActiveSpreadsheet();
for(var i in sheets){
var sheet = sheets[i];
var data = sheet.getDataRange().getValues();
var destSheet = current.getSheetByName(sheet.getName());
if(destSheet){
destSheet.getRange(1,1,destSheet.getMaxRows(),destSheet.getMaxColumns()).clearContent();
destSheet.getRange(1,1,data.length,data[0].length).setValues(data);
Logger.log(sheet.getName() + " imported");
}else{
var newSheet = current.insertSheet(sheet.getName());
newSheet.getRange(1,1,data.length,data[0].length).setValues(data);
Logger.log(sheet.getName() + " created");
}
}
}
Stéphane