Ok, I'm in need of some help optimising (where possible) and error checking my code.
My code has ran error free for 20+ weeks. Now all of a sudden, the script 'hangs' while executing the .setvalues on line 190. This is the section that archives the information.
Error received is "Service Timed Out : Spreadsheets" and "Exception: Service Error: Spreadsheets".
The Scripts runs between 2-3am on Sundays, when the servers should be less congested. The Script has also never timed out when running manually. I have not been able to replicate this error, even when tripling or quadrupling the working data.
So, I'll start.
My script runs in 4 sections.
Section 1 :
Validate information - Remove filters, Unhide Rows/columns and delete blank rows.
Section 2 :
Copy the selected sheet to a new spreadsheet and email this to selected users as an attachment in Excel format.
Section 3 :
Clear the data from the original sheet to prevent the possibility of duplication.
Section 4 :
This is the part that fails, TRY and paste the copied values into the archived spreadsheet.
Previously, there was no loop to re-attempt this. If it failed I would receive an email with the excel document.
The loop doesn't seem to be helping. Other than, it pasted half the information into my archive this weekend past.
If this helps, the data that is being moved is about 8000 rows and 15 columns, so about 120,000 cells. (Not that much)
If anyone can suggest any amendments or improvements, please feel free.
Full code below.
//******************** Menu Start ************************//
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Admin')
.addItem('Update to Raw', 'moveData')
.addSeparator()
.addSubMenu(ui.createMenu('Authorise')
.addItem('Authorise Scripts', 'Auth'))
.addToUi();
}
//******************** Menu End ************************//
//******************** Authorisation Start ************************//
function Auth(){
var email = Session.getActiveUser().getEmail();
var temp = new Date();
if (temp == "Blank") {
// These calls will never be visited
onOpen();
moveData();
clearData();
RemoveFilter();
DeleteBlankRows();
UnhideAllRowsAndColumns();
UnhideAllRowsAndColumnsRaw();
clearDataRaw();
} else {
Browser.msgBox("The Backup script has now been authorized for "+email+". Each user only has to do this once.");
}
}
//******************** Authorisation End ************************//
//******************** Clear Source Sheet Start ************************//
function clearData() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var source = Spreadsheet.getSheetByName("Data");
source.deleteRows(2,source.getLastRow()-1);
}
//******************** Clear Source Sheet End ************************//
//******************** Copy Data Start ************************//
function ArchiveData() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var source = Spreadsheet.getSheetByName("Data");
var targetkey = Spreadsheet.getSheetByName("Archive").getRange("C1").getValue();
var tSpreadsheet = SpreadsheetApp.openById(targetkey);
var target = tSpreadsheet.getSheetByName("Raw");
try{
// Information Quality Checks
RemoveFilter();
UnhideAllRowsAndColumns();
DeleteBlankRows();
var storedata = source.getRange(2,1,source.getLastRow(),source.getLastColumn()).getValues();
var sn = Spreadsheet.getName();
var URL = Spreadsheet.getUrl();
var message = URL;
var date = Utilities.formatDate(new Date(), "GMT+1", "dd-MM-yyyy HH:mm");
var subject = sn + " - Script Complete : " + date;
var emailTo = ["Recipient1#gmail.co.uk","Recipient2#gmail.co.uk",
"Recipient3#gmail.co.uk","Recipient4#gmail.co.uk","Recipient5#gmail.co.uk"];
// Google Sheets Extract Sheet Hack //
// Create a new Spreadsheet and copy the current sheet into it//
var newSpreadsheet = SpreadsheetApp.create("Call Log Script Export");
source.copyTo(newSpreadsheet);
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
// newSpreadsheet.getSheetByName('!Copied Sheet Name!').setName("Source Export") //
var ssID = newSpreadsheet.getId();
var url = "https://docs.google.com/spreadsheets/d/" + ssID + "/export?format=xlsx&id=" + ssID;
var requestData = {"method": "GET","headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var result = UrlFetchApp.fetch(url , requestData);
var contents = result.getContent();
MailApp.sendEmail(emailTo, subject, message,
{attachments:[{fileName:"Call Log Script Export.xls", content:contents, mimeType:"application//xls"}]});
//------------------------- Move Data -------------------------//
var senddata = target.getRange(target.getLastRow()+1, 1, source.getLastRow(),source.getLastColumn() );
//------------------------- Clear Data Call -------------------------//
// ------------- Clears Source Sheet ------------- //
clearData();
var retryLimit = 4;
var retryDelay = 1000;
var retry;
for (retry = 0; retry <= retryLimit; retry++) {
try {
// do the spreadsheet operation that might fail
senddata.setValues(storedata);
// Delete the wasted sheet we created, so our Drive stays tidy
DriveApp.getFileById(ssID).setTrashed(true);
SpreadsheetApp.flush();
break;
}
catch (e) {
Logger.log('Failed on try ' + retry + ', exception: ' + e);
if (retry == retryLimit) {
throw e;
}
Utilities.sleep(retryDelay);
}
}
//------------------------- Copy Data Mid -------------------------//
}
//------------------------- Catch and Send Error Start -------------------------//
catch(err){
var error = err.lineNumber + ' - ' + err;
var URL = Spreadsheet.getUrl();
var sn = Spreadsheet.getName();
var date = Utilities.formatDate(new Date(), "GMT+1", "dd-MM-yyyy HH:mm");
var emailadd = ["Recipient1#gmail.co.uk","Recipient2#gmail.co.uk",
"Recipient3#gmail.co.uk","Recipient4#gmail.co.uk","Recipient5#gmail.co.uk"];
var subject = sn + " : Archive Script Error";
var body = URL + " - - - Date - - - " + date + " - - - Error Code - - - " + error
MailApp.sendEmail(emailadd,subject,body);
}
//------------------------- Catch and Send Error End -------------------------//
}
//******************** Copy Data End ************************//
//******************** Unhide Start ************************//
function UnhideAllRowsAndColumns() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var source = Spreadsheet.getSheetByName("Data");
var fullSheetRange = source.getRange(1,1,source.getMaxRows(), source.getMaxColumns() )
source.unhideColumn( fullSheetRange );
source.unhideRow( fullSheetRange ) ;
}
//******************** Unhide End ************************//
//******************** Delete Blank Start ************************//
function DeleteBlankRows() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var source = Spreadsheet.getSheetByName("Data");
var rows = source.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[1] == '') {
source.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
}
//******************** Delete Blank End ************************//
//******************** Remove Filter Start ************************//
function RemoveFilter(){
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var source = Spreadsheet.getSheetByName("Data");
var row = 1 //the row with filter
var rowBefore = row
source.insertRowBefore(row); //inserts a line before the filter
row++;
var Line = source.getRange(row + ":" + row); //gets filter line in A1N
Line.moveTo(source.getRange(rowBefore + ":" + rowBefore)); //move to new line in A1N
source.deleteRow(row); //deletes the filter line
}
//******************** Remove Filter End ************************//
I looked over the code pretty thoroughly and I don't see any obvious problems. But I'm curious about this line:
var senddata = target.getRange(target.getLastRow()+1, 1, source.getLastRow(),source.getLastColumn() );
Since I can't see your data I can't confirm that the range height and width for senddata are the same as the dimensions of storedata and if they aren't then that could cause a problem.
"Service Timed Out : Spreadsheets"
error started happening on my script today and after a few trials what I could do to get away with that was to:
Make a full copy of the sheet (that contains script) and start using that sheet.
Cheers,
So here's what's bugging me:
var storedata = source.getRange(2,1,source.getLastRow(),source.getLastColumn()).getValues();
var senddata = target.getRange(target.getLastRow()+1, 1, source.getLastRow(),source.getLastColumn() );
storedata is an array that has to have the same dimensions as the range senddata.
number of rows in the storedata range is source.getLastRow()-1.
number of columns in the storedata range is source.getLastColumn() = 15
number of rows in senddata is source.getLastRow() - target.getLastRow() + 1
number of columns in senddate is source.getLastColumn() = 15
so:
source.getLastRow()-1 = source.getLastRow() - target.getLastRow() + 1
// add 1 to both sides
source.getLastRow() = source.getLastRow() - target.getLastRow() + 2
subtract source.getLastRow() from both sides
target.getLastRow() = 2 //is this true
Is that always true? Or am I just totally off the mark here.
Related
I have a macro script that runs in the background of a Google Sheet, which archives (copies and pastes values) from a tab with formulas to a new archive tab without formulas when the number of rows in the formula tab exceeds 10. This allows the sheet to not slow down as the number of rows increases with all the built in formulas.
The macro broke a few days ago and nothing has changed, except for this new error I see in the script editor.
Here is the code to return the last row of the sheet we are archiving (with formulas). And the error message is telling me this part of the code broke.
var Direction=SpreadsheetApp.Direction;
var DailySLast =dailySheet.getRange("A"+(dailySheet.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
And here is the error message pointing to the .getNextDataCell part
Exception: Invalid argument
myFunction # Code.gs:8
Any idea why this is happening?
===================
4/20/2021 update
Below is the entire function
function myFunction() {
// Get handles to Daily and Archive sheets
var dailySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Scorecard');
var appendSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('[Archive] Scorecard');
//get last row of the daily sheet
var Direction=SpreadsheetApp.Direction;
var DailySLast =dailySheet.getRange("A"+(dailySheet.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
//Range of cells to be copied
var CopyRange = "Scorecard!9:" + DailySLast;
//Range of cells to be deleted
var DelRange = "Scorecard!9:" + 2000;
//get last row of the archive sheet
var ArchiveSLast =appendSheet.getRange("A"+(appendSheet.getLastRow()+1)).getNextDataCell(Direction.UP).getRow();
//copying destination range
var destrange1 = "[Archive] Scorecard!" + (ArchiveSLast + 1) + ":" + (ArchiveSLast + DailySLast-8);
var destrange= dailySheet.getRange(destrange1);
// Clear the contents only if Underwriting sheet has more than 10 rows of data
if(DailySLast>10) {
//copying the data
var sourceDataValues = dailySheet.getRange(CopyRange).copyTo(destrange,SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
// Get the formulas from the sheet
var formulas = dailySheet.getRange(DelRange).getFormulas();
// Delete the data from the daily sheet
dailySheet.getRange(DelRange).clearContent();
//Put the formulas back in the sheet
dailySheet.getRange(DelRange).setFormulas(formulas)};
//Browser.msgBox(DailySLast, Browser.Buttons.OK_CANCEL);
}
function testquestion() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
const rg = sh.getRange(sh.getLastRow()+1,1);
let r = rg.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(r),'Test');
}
I get the same result if there are no available rows at the bottom of the spreadsheet
Execution log
3:44:46 PM Notice Execution started
3:44:46 PM Error
Exception: Invalid argument
testquestion # ag1.gs:5
In this case getLastRow()+1 doesn't exist because there are no more rows.
Something like this might solve the problem for you:
function testquestion() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
//add this section to prevent error
let lr=sh.getLastRow();
let mr=sh.getMaxRows();
if(lr==mr) {
sh.insertRowAfter(mr);
}
//end of section
const rg = sh.getRange(sh.getLastRow()+1,1);
let r = rg.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(r),'Test');
}
Update:
function myFunction() {
// Get handles to Daily and Archive sheets
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Scorecard');
var appendSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('[Archive] Scorecard');
//add this section to prevent error
let lr = sh.getLastRow();
let mr = sh.getMaxRows();
if (lr == mr) {
sh.insertRowAfter(mr);
}
//end of section
//get last row of the daily sheet
var Direction = SpreadsheetApp.Direction;
var DailySLast = sh.getRange("A" + (sh.getLastRow() + 1)).getNextDataCell(Direction.UP).getRow();
//Range of cells to be copied
var CopyRange = "Scorecard!9:" + DailySLast;
//Range of cells to be deleted
var DelRange = "Scorecard!9:" + 2000;
//get last row of the archive sheet
var ArchiveSLast = appendSheet.getRange("A" + (appendSheet.getLastRow() + 1)).getNextDataCell(Direction.UP).getRow();
//copying destination range
var destrange1 = "[Archive] Scorecard!" + (ArchiveSLast + 1) + ":" + (ArchiveSLast + DailySLast - 8);
var destrange = sh.getRange(destrange1);
// Clear the contents only if Underwriting sheet has more than 10 rows of data
if (DailySLast > 10) {
//copying the data
var sourceDataValues = sh.getRange(CopyRange).copyTo(destrange, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
// Get the formulas from the sheet
var formulas = sh.getRange(DelRange).getFormulas();
// Delete the data from the daily sheet
sh.getRange(DelRange).clearContent();
//Put the formulas back in the sheet
sh.getRange(DelRange).setFormulas(formulas)
};
I have two scripts:
One which adds an IMPORTJSON sheets function from bradjasper, works great.
The second one is that I want to refresh the scripts automatically, that does not work. The script does work when I ran it manually, and also the trigger does work according to the logs, but the data does not get refreshed.
I have tried all the different scripts, they do work, but the data imported on the sheet is not actually updated.
function RefreshImports() {
var lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) return; // Wait up to 5s for previous refresh to end.
var id = "1Vt-rqQZ7iXsui8Nrr2XABusd4lUbGqxj4HkzsRkZFNA";
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("Blad2");
var dataRange = sheet.getDataRange();
var formulas = dataRange.getFormulas();
var content = "";
var now = new Date();
var time = now.getTime();
var re = /.*[^a-z0-9]import(?:xml|data|feed|html|json|range)\(.*/gi;
var re2 = /((\?|&)(update=[0-9]*))/gi;
var re3 = /(",)/gi;
for (var row=0; row<formulas.length; row++) {
for (var col=0; col<formulas[0].length; col++) {
content = formulas[row][col];
if (content != "") {
var match = content.search(re);
if (match !== -1 ) {
// import function is used in this cell
var updatedContent = content.toString().replace(re2,"$2update=" + time);
if (updatedContent == content) {
// No querystring exists yet in url
updatedContent = content.toString().replace(re3,"?update=" + time + "$1");
}
// Update url in formula with querystring param
sheet.getRange(row+1, col+1).setFormula(updatedContent);
}
}
}
}
// Done refresh; release the lock.
lock.releaseLock();
// Show last updated time on sheet somewhere
sheet.getRange(1,1).setValue("Rates were last updated at " + now.toLocaleTimeString())
}
This script does run, as there are no errors in the logs. However, the data shown on the sheet does not change to reflect the current information from the API / JSON file.
Google App script not firing all JavaScript pop up boxes using on edit trigger. Does not fire when a change is made to the sheet for multiple users. Also only works when it feels like it. I have set the trigger to onEdit(). My code:
function Error() {
var sheet = SpreadsheetApp.getActiveSheet();
if (sheet.getName() == "Protocal Check List 2"){
var ui = SpreadsheetApp.getUi(); // Same variations.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var active = ss.getActiveCell();
var getactive = ss.getActiveCell().getDisplayValue();
var column = ss.getActiveRange().getColumn();
var row = ss.getActiveRange().getRow();
var msg = '';
var section = sheet.getRange('C'+ row);
switch (column) {
case 9:
var msg = "error 1";
break;
case 10:
var msg = "Error 2";
break;
default:
msg = "Error";
break;
}
if(getactive == "TRUE"){
if(column >= 9 && column <= 60
){
var result = ui.alert(
"pika Says",
msg,
ui.ButtonSet.YES_NO);
// Process the user's response.
if (result == ui.Button.YES) {
// User clicked "Yes".
window.alert('Task Complete: \n\n' + msg);
active.setValue('True');
} else {
var i = 0;
while (i < 1) {
var result = ui.prompt(
'Please detail cause of the problem:',
ui.ButtonSet.OK);
var text = result.getResponseText();
var textcount = text.length;
if(textcount > 0) {
i++;
}}
var cell = "H" + row;
var emailAddress = "email#gmail.com";
var d = new Date();
var n = d.toDateString();
var t = d.toTimeString();
var staffname = ss.getRange(cell).getValues();
var message = "Date: " + n +"\n\nTime: " + t +"\n\nStaff: " + staffname + "\n\nError: " + msg + "\n\nProblem: " + text;
var subject = msg;
var thedate = n + " / " + t;
ss.getRange('A1').setValue(thedate);
ss.getRange('B1').setValue(staffname);
ss.getRange('C1').setValue(msg);
ss.getRange('D1').setValue(text);
var s1 = ss.getRange('A1:D1'); //assign the range you want to copy
var s1v = s1.getValues();
var tss = SpreadsheetApp.openById('1mOzdRgKxiP5iB9j7PqUWKKo5oymWuAeQZ1jJ1s6qL9E'); //replace with destination ID
var ts = tss.getSheetByName('AB Protocal'); //replace with destination Sheet tab name
ts.getRange(ts.getLastRow()+1, 1, 1,4).setValues(s1v); //you will need to define the size of the copied data see getRange()
MailApp.sendEmail(emailAddress, subject, message);
// User clicked "No" or X in the title bar.
//ui.alert("The following note has been sent to the Duty Manager: \n\n" + text);
active.setValue('FALSE');
}}}}
}
Any help would be appreciated. I need it to run every signal time for users who have access to the sheet.
You'll have to
assume that onEdit triggers are best-effort, but may not catch all
edits done to the spreadsheet.
Bug thread is here.
To get around the bug as mentioned by Edward implemente a dumb router.
// create a new file -> router.gs
function routerOnEdit(e) {
myOnEditHook1(e);
myOnEditHook2(e);
myOnEditHook3(e);
}
I have submitted an issue, which is the updated version of a long-running 7 year issue. They closed it in 2022, saying the feature is intended. They have now added a feature where onEdit can queue up to 2 trigger events. The issue I'm having is that the second edit still does not trigger. Despite what the documentation says.
Note: The onEdit() trigger only queues up to 2 trigger events.
View the new issue here: https://issuetracker.google.com/issues/221703754
I want to force an importXML to auto-refresh every five minutes. This is the script I am trying to run and getting the error "Bad value (line 7, file "RefreshImports" . I do not know why. I found it here: Periodically refresh IMPORTXML() spreadsheet function
function RefreshImports() {
var lock = LockService.getScriptLock();
if (!lock.tryLock(5000)) return; // Wait up to 5s for previous
refresh to end.
var id = "[YOUR SPREADSHEET ID]";
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("[SHEET NAME]");
var dataRange = sheet.getDataRange();
var formulas = dataRange.getFormulas();
var content = "";
var now = new Date();
var time = now.getTime();
var re = /.*[^a-z0-9]import(?:xml|data|feed|html|range)\(.*/gi;
var re2 = /((\?|&)(update=[0-9]*))/gi;
var re3 = /(",)/gi;
for (var row = 0; row < formulas.length; row++) {
for (var col = 0; col < formulas[0].length; col++) {
content = formulas[row][col];
if (content != "") {
var match = content.search(re);
if (match !== -1) {
// import function is used in this cell
var updatedContent = content.toString().replace(re2, "$2update=" +
time);
if (updatedContent == content) {
// No querystring exists yet in url
updatedContent = content.toString().replace(re3, "?update=" + time +
"$1");
}
// Update url in formula with querystring param
sheet.getRange(row + 1, col + 1).setFormula(updatedContent);
}
}
}
}
// Done refresh; release the lock.
lock.releaseLock();
// Show last updated time on sheet somewhere
sheet.getRange(7, 2).setValue("Rates were last updated at " +
now.toLocaleTimeString())
}
In the code where it says "[YOUR SPREADSHEET ID]", I am to enter the name of my spreadsheet correct? I do not know anything about this.
On [YOUR SPREADSHEET ID] you should add the spreadsheet id, not it's name.
The spreadsheet id for
https://docs.google.com/spreadsheets/d/1Xhgfr3z4EwPtjS4aahytU_3TOVxjNb8JvHo88h3nZaE/edit#gid=14522064
is
1Xhgfr3z4EwPtjS4aahytU_3TOVxjNb8JvHo88h3nZaE
I found it easier to use the URL instead the id, here is the bit of code:
var url = "URL OF SPREADSHEET";
var sheetName = "NAME OF SPECIFIC SHEET";
var ss = SpreadsheetApp.openByUrl(url);
var sheet = ss.getSheetByName(sheetName);
I'm getting this error while running this sheet.
Cell reference out of range (line 81, file "genreportSE")
I don't know why it says it's 'out of range'.
I tried to used 'copyvalues'. I saw a script where you can't really "print" a range, but you can create another spreadsheet, copy that range, then print that sheet and delete it.
How should I accomplish this?
function genreportSE() { // This function let us read the value of a cell from a sheet and change the value of another cell in a different sheet
var ss = SpreadsheetApp.getActive(); //ss stands for spreadsheet, this is the active spreadsheet
var clientsheet = ss.getSheetByName('Clientes SE');
var gensheet = ss.getSheetByName('Generador SE');
var clienttable = clientsheet.getDataRange();
var numberofservices = clienttable.getNumRows(); //The number of services in the Clientes sheet
var error1;
var error2;
var rangetocheck1;
var rangetocheck2;
var client;
var clientname;
var i=0;
var reportswitherrors = []; //Array for faulty reports
var email ='jvaldez#galt.mx';
var subject = "Reporte de producción y consumo - " + (new Date()).toString();
var body = "TEXT" ;
for (i=0;i<=2;i++){
gensheet.getRange('B2').setValue(clientsheet.getRange(i+2,1).getValue()); //This will change the cell "B2" in "Generador SE" to the current service number for the report generation
Utilities.sleep(3000); //A timer to let the importdata function get the data from the SE server in miliseconds
client = gensheet.getRange('B4').getValue;
clientname = String(client);
rangetocheck1 = gensheet.getRange('B8:C14').getValues(); //Data range that could present calculation errors ********
rangetocheck2 = gensheet.getRange('H8:H14').getValues(); //Data range that could present calculation errors ********
if(String(rangetocheck1).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck1
error1 = false;
} else {
error1 = true;
};
if(String(rangetocheck2).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck2
error2 = false;
} else{
error2 = true;
};
if(error1||error2){
reportswitherrors.push(clientsheet.getRange(i+2,1).getValue()); //This appends the current service number to the faulty services array
} else {
// Convert individual worksheets to PDF
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
newSpreadsheet.getSheetByName('Sheet1').activate();
var newsheet = newSpreadsheet.getSheetByName('Sheet1');
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)
var pdf = DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Weekly Status.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(email, subject, body, {attachments:[attach]});
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
}
};
Logger.log(reportswitherrors);
}
It appears that you've got your row & column dimensions flipped between function calls. (Because Google decided to be inconsistent with the order of them...)
This line calls create(name, rows, columns):
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
You've created a spreadsheet with 15 rows and 60 columns.
A bit further along, probably on line 81, copyValuesToRange(sheet, column, columnEnd, row, rowEnd) gets invoked:
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)