I am scraping a few pages every day and need to create a new google sheet in order to put the scraped data in it.
I am looping through the pages and if it is the first page, I create a new ss with the date as a name.
Then for subsequent pages, I am trying to get this same page by name reference in order to add the data from page 2,3,...
Here is the code:
if(start==1){
// Create new ss in current folder
var ss = SpreadsheetApp.create(full_d);
var id = ss.getId();
var file = DriveApp.getFileById(id);
var folder = DriveApp.getFolderById('ABC');
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
}else{
var ss = SpreadsheetApp.getSheetByName(full_d);
}
ss.getRange(ss.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
If I delete the if statement and just put var ss = Spreadsheet.getActiveSheet(), my code works.
Thanks
How about this modification?
Modification points :
The sheet in the created Spreadsheet using getSheets() was given.
When start is not 1, an error occurs at var ss = SpreadsheetApp.getSheetByName(full_d);. So it was modified that the spreadsheet with the filename of full_d is opened.
The scope of ss was considered. But in GAS, this may not be a problem.
Modified script :
var ss; // <--- Added
if(start==1){
// Create new ss in current folder
ss = SpreadsheetApp.create(full_d);
var id = ss.getId();
var file = DriveApp.getFileById(id);
var folder = DriveApp.getFolderById('ABC');
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
ss = ss.getSheets()[0]; // <--- Added
}else{
var file = DriveApp.getFilesByName(full_d).next(); // <--- Added
ss = SpreadsheetApp.open(file).getSheets()[0]; // <--- Added
}
ss.getRange(ss.getLastRow() + 1, 1, res.length, res[0].length).setValues(res);
If I misunderstand your question, I'm sorry. At that time, please tell me.
Related
I am using this code:
function copyInfo() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Product-analyse");
var pasteSheet = ss.getSheetByName("Blad18"); // get source range
var source = copySheet.getRange(93,7,39,6); // get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range
source.copyTo(destination); // clear source values
source.clearContent();
}
Now its pasting in "Blad18". Instead I want it to be pasted in another file.
I tried adding {contentOnly: TRUE}. Though this didnt seem to work
I cannot figure this out unfortunately. Everything else is correctly set already.
Any help is greatly appreciated.
Updated script I am using:
function copyInfo() {
var ssSource = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ssSource.getSheetByName("Product-analyse");
var ssPaste = SpreadsheetApp.openById("1qhnA8L3ZkU-iEyOJtszAC4OW58sg2TJZSa_rmN_EXBI"); // the id of the other spreadsheet
var pasteSheet = ssPaste.getSheetByName("Submitted Data"); // get source range
var source = copySheet.getRange(93,7,39,6); // get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range
source.copyTo(destination); // clear source values
source.clearContent();
}
Try this:
function copyInfo() {
var ss = SpreadsheetApp.getActive();
var csh = ss.getSheetByName("Sheet0");
var psh = ss.getSheetByName("Sheet1");
const cshsr = 2;
var crg = csh.getRange(cshsr, 1, csh.getLastRow() - cshsr + 1, csh.getLastColumn());
var prg = psh.getRange(psh.getLastRow() + 1, 1);
crg.copyTo(prg);
}
I believe what you want to do is copy from one spreadsheet file to another spreadsheet file. Here is an example
function copyInfo() {
var ssSource = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ssSource.getSheetByName("Product-analyse");
var ssPaste = SpreadsheetApp.openById("dfsfhsfhskfhaskjfhsjkfas"); // the id of the other spreadsheet
var pasteSheet = ssPaste.getSheetByName("Blad18"); // get source range
var source = copySheet.getRange(93,7,39,6); // get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,39,6); // copy values to destination range
source.copyTo(destination); // clear source values
source.clearContent();
}
Reference
SpreadsheetApp.openById()
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"));
}
I am trying to link a Google Sheets file with a Google Doc file and replace the text of the Google Docs with some custom items.
Exception: Invalid argument: sheet
autoFillGoogleDocFromForm # Code.gs:5
This error is generated by the following code. I used (name of sheet), (file id inserted), (folder id inserted) instead of showing the actual values.
function autoFillGoogleDocFromForm(e) {
var activateSheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(activateSheet.getSheetByName('(name of sheet)'));
var sheet = SpreadsheetApp.getActiveSheet();
var row = e.range.getRowIndex();
var timestamp = sheet.getRange(row, 1).getValues();
var file = DriveApp.getFileById('(file id inserted)');
var folder = DriveApp.getFolderById('(folder id inserted)');
var copy = file.makeCopy('' + timestamp, folder);
var doc = DocumentApp.openById(copy.getId());
var header = doc.getHeader();
header.replaceText('{{TIMESTAMP}}', timestamp);
doc.saveAndClose();
}
You can simplify the way you define a Sheet:
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet = ss.getSheetByName('name of the sheet')
Even if you are not going to use the Spreadsheet object any more, you can directly define the Sheet object
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('name of the sheet')
Make sure you write the name of the sheet properly.
and thanks for the help. I've got a noob question, and need a noob answer.
Trying to email a specific google sheet as a pdf weekly, but script emails out whatever sheet happens to be open at the time.
Stole various snippets of code, here's what I've got: (And no, I don't think that this block of code was formatted and posted correctly.)
function endOfWK_1 () {
//This script converts all formulas to values in the currently displayed sheet, then converts the currently displayed sheet to a pdf, then emails the
pdf as an attachment to the addresses shown in cell B17 in the "Email" sheet.
//Replace all formulas in range "WK 1!A6:A29" with values
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('WK 1');
var range = sheet.getRange("WK 1!A6:A29");
range.copyTo(range, {contentsOnly: true});
// FOR WK1 ONLY!!!
// Set the Active Spreadsheet so we don't forget
var originalSpreadsheet = SpreadsheetApp.getActive();
// Set the message to attach to the email.
var message = "Please see attached.";
// Get Dates from Email!B5
var period = originalSpreadsheet.getRange("Email!B5").getValues();
// Construct the Subject Line
var subject = period;
// Get contact details from "Email" sheet and construct To: Header
var contacts = originalSpreadsheet.getSheetByName("Email");
var numRows = contacts.getLastRow();
var emailTo = contacts.getRange(17, 2, numRows, 1).getValues();
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
sheet = originalSpreadsheet.getActiveSheet();
sheet.copyTo(newSpreadsheet);
// Find and delete the default "Sheet1"
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
// Create the PDF, currently called "Tracking Sheet.pdf"
var pdf = DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Tracking Sheet.pdf',content:pdf, mimeType:'application/pdf'};
// Send the freshly constructed email
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
// Delete the sheet that was created
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
// Write the date and time that the script ran
var date = sheet.getRange('Statistics!A1').getValues();
SpreadsheetApp.getActiveSheet().getRange('Analysis!E5').setValues(date);
}
This is a bound script, attached to a google workbook containing 5 sheets. My problem is that my script always emails the sheet that happens to be open at the time.
I want to email one specific sheet, whether the workbook is open or closed. How can I do this? (I hope to install a trigger to make this script run automatically.)
Also, anyone want to critique my code?
Thanks to all.
I've fixed it up a little and added some comments. There were a lot of little things I fixed up biggest thing was that you should reuse variables that you've created.
This hasn't been tested...
function endOfWK_1 () {
//Replace all formulas in range "WK 1!A6:A29" with values
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetWK1 = activeSpreadsheet.getSheetByName('WK 1');
var range = sheetWK1.getRange("WK 1!A6:A29");
range.copyTo(range, {contentsOnly: true});
// FOR WK1 ONLY!!!
// Set the Active Spreadsheet so we don't forget
var originalSpreadsheet = SpreadsheetApp.getActive(); //this should probably be changed depending on what sheet you are trying to access: activeSpreadsheet.getSheetByName('Email')
// Set the message to attach to the email.
var message = "Please see attached.";
// Get Dates from Email!B5
var period = originalSpreadsheet.getRange("Email!B5").getValues();
// Construct the Subject Line
var subject = period;
// Get contact details from "Email" sheet and construct To: Header
var contacts = originalSpreadsheet.getSheetByName("Email");
var numRows = contacts.getLastRow();
var emailTo = contacts.getRange(17, 2, numRows, 1).getValues();
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export"); //Create a spreadsheet to copy to
// var originalSheet = activeSpreadsheet.getSheetByName("WK1"); Already defined above as sheetWK1
//var projectname = SpreadsheetApp.getActiveSpreadsheet(); Seems like this is not used.
sheetWK1.copyTo(newSpreadsheet); //Take the original sheet and copy it to the newSpreadsheet
// Find and delete the default "Sheet1"
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Sheet1")); //We can just call the deleteSheet method.
// Create the PDF, currently called "Tracking Sheet.pdf"
var pdf = newSpreadsheet.getAs('application/pdf').getBytes(); //No need to get the Spreadsheet object again, as we alreat have it!
var attach = {fileName: 'Tracking Sheet.pdf', content: pdf, mimeType: 'application/pdf'};
// Send the freshly constructed email
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
// Delete the sheet that was created
newSpreadsheet.setTrashed(true); //Again no need to find the object. We have it.
// Write the date and time that the script ran
var date = sheet.getRange('Statistics!A1').getValues();
activeSpreadsheet.getRange('Analysis!E5').setValues(date);
}
The main issue was var originalSpreadsheet = SpreadsheetApp.getActive(); you are getting the active sheet and using that to create you pdf.
EDIT: I've cleaned up the whole thing a little and ended up with this. It hasn't been tested.
function endOfWK_1 () {
//Replace all formulas in range "WK 1!A6:A29" with values
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetWK1 = activeSpreadsheet.getSheetByName('WK 1');
var emailSheet = activeSpreadsheet.getSheetByName("Email");
var range = sheetWK1.getRange("WK 1!A6:A29");
range.copyTo(range, {contentsOnly: true});
// FOR WK1 ONLY!!!
// Set the message to attach to the email.
var message = "Please see attached.";
// Get Dates from Email!B5
var period = emailSheet.getRange("Email!B5").getValues();
// Construct the Subject Line
var subject = period;
// Get contact details from "Email" sheet and construct To: Header
var numRows = emailSheet.getLastRow();
var emailTo = emailSheet.getRange(17, 2, numRows, 1).getValues();
// Create a new Spreadsheet and copy the current sheet into it.
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export");
sheetWK1.copyTo(newSpreadsheet);
// Find and delete the default "Sheet1"
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Sheet1"));
// Create the PDF, currently called "Tracking Sheet.pdf"
var pdf = newSpreadsheet.getAs('application/pdf').getBytes();
var attach = {fileName: 'Tracking Sheet.pdf', content: pdf, mimeType: 'application/pdf'};
// Send the freshly constructed email
MailApp.sendEmail(emailTo, subject, message, {attachments:[attach]});
// Delete the sheet that was created
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
// Write the date and time that the script ran
var date = activeSpreadsheet.getRange('Statistics!A1').getValues();
activeSpreadsheet.getRange('Analysis!E5').setValues(date);
}
I am working on a google script to import CSV files from web urls to individual sheets in a google sheet. I would like to have it clear the contents of certain columns before importing the new info. I had had trouble getting the script to clear contents prior to importing. I have also had in include part of one CSV along with another on a sheet. I think I need to add something to the script between CSV files. I also need something added to clear contents prior to importing. I don't want to just clear the sheet because there are formulas that need to remain. I also don't want to use the Google IMPORTDATA function because it is unreliable.
Here is my current script (URLs removed):
function importCSVFromWeb() {
var csvUrl = "http://csvurlhere";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var ss = SpreadsheetApp.openByUrl('spreadsheeturlhere');
var sheet = SpreadsheetApp.getActiveSheet();
var ss = sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
var csvUrl = "http://csvurlhere";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var sheet = SpreadsheetApp.getActive().getSheetByName('RentPaid');
var ss = sheet.getRange(3, 3, csvData.length, csvData[0].length).setValues(csvData);
var csvUrl = "http://csvurlhere";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var sheet = SpreadsheetApp.getActive().getSheetByName('Tenants');
var ss = sheet.getRange(1, 2, csvData.length, csvData[0].length).setValues(csvData);
var csvUrl = "http://csvurlhere";
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var sheet = SpreadsheetApp.getActive().getSheetByName('Owners');
var ss = sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
To clear the contents of a sheet or a range of cells within a sheet, you can use sheet.clearContents() or range.clearContent(), which will remove only values & leave your formatting & formulas in tact.
I note that your line var ss = SpreadsheetApp.openByUrl('spreadsheeturlhere'); does nothing as you subsequently redeclare the ss variable. If the script is bound to a spreadsheet, you don't need this line as calls to getActive() & getActiveSheet() will give you a reference to the host spreadsheet. Your calls to SpreadsheetApp.getActive().getSheetByName() are returning references to the host spreadsheet anyway, not the one you open by URL.
I would also consider changing your function to accept the CSV source URLs, sheet names & cell anchors as parameters so that the code is easier to maintain. e.g.
function importCSVFromWeb(csvUrl, sheetName, dataAnchor) {
/* csvUrl: the CSV source URL
sheetName: the name of the sheet to add the data
dataAnchor: the cell origin for the range.setValues() call as an array
i.e. dataAnchor = [row, col]
*/
var csvContent = UrlFetchApp.fetch(csvUrl).getContentText();
var csvData = Utilities.parseCsv(csvContent);
var ss = SpreadsheetApp.getActive();
// note that you'll need to pass in a name for each sheet,
// including the first one where you used SpreadsheetApp().getActiveSheet() previously
var sheet = ss.getSheetByName(sheetName);
sheet.getRange(dataAnchor[0], dataAnchor[1], csvData.length, csvData[0].length).setValues(csvData);
}
function feedCSVImport(){
var urls_sheets_list = [["csv_source_url_1", "Sheet1", [1,1]],
["csv_source_url_2", "RentPaid", [3,3]],
["csv_source_url_3", "Tenants", [1,2]],
["csv_source_url_4", "Owners", [1,1]]
];
for(var i = 0, lim = url_sheets_list.length; i < lim; ++i){
importCSVFromWeb(url_sheets_list[i][0], url_sheets_list[i][1], url_sheets_list[i][2]);
}
}