I want to email a specified range from the current active google sheet.There is an error with this code,it says TypeError: SpreadsheetApp.getActiveSpreadsheet(...).getRange(...).getAs is not a function Line 9
function sendReport() {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Responses").hideSheet();
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form").activate();
var message = {
to: SpreadsheetApp.getActiveSheet().getRange('L2').getValue(),
subject: "Monthly sales report",
body: "Hi team,\n\nPlease find the monthly report attached.\n\nThank you,\nBob",
name: "Bob",
attachments: [SpreadsheetApp.getActiveSpreadsheet().getRange("Form!A5:H25").getAs(MimeType.PDF).setName("Monthly sales report")]
}
MailApp.sendEmail(message);
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Responses").activate();
}
You cannot convert a sheet content to pdf with getAs(MimeType.PDF) alone
A way to send a sheet range as a pdf attachment would be to convert it a pdf blob first, as perfomed by Alan Wells in the post linked by JPV.
Based on this conversion, you can modify your code as following:
var ss = SpreadsheetApp.getActiveSpreadsheet();
function sendReport() {
var sheetTabNameToGet = "Form";
var range = "A5:H25";
var pdfBlob = exportRangeToPDf(range, sheetTabNameToGet);
var message = {
to: ss.getSheetByName(sheetTabNameToGet).getRange('L2').getValue(),
subject: "Monthly sales report",
body: "Hi team,\n\nPlease find the monthly report attached.\n\nThank you,\nBob",
name: "Bob",
attachments: [pdfBlob.setName("Monthly sales report")]
}
MailApp.sendEmail(message);
}
function exportRangeToPDf(range, sheetTabNameToGet) {
var blob,exportUrl,options,pdfFile,response,sheetTabId,ssID,url_base;
ssID = ss.getId();
sh = ss.getSheetByName(sheetTabNameToGet);
sheetTabId = sh.getSheetId();
url_base = ss.getUrl().replace(/edit$/,'');
exportUrl = url_base + 'export?exportFormat=pdf&format=pdf' +
'&gid=' + sheetTabId + '&id=' + ssID +
'&range=' + range +
'&size=A4' + // paper size
'&portrait=true' + // orientation, false for landscape
'&fitw=true' + // fit to width, false for actual size
'&sheetnames=true&printtitle=false&pagenumbers=true' + //hide optional headers and footers
'&gridlines=false' + // hide gridlines
'&fzr=false'; // do not repeat row headers (frozen rows) on each page
options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
options.muteHttpExceptions = true;//Make sure this is always set
response = UrlFetchApp.fetch(exportUrl, options);
if (response.getResponseCode() !== 200) {
console.log("Error exporting Sheet to PDF! Response Code: " + response.getResponseCode());
return;
}
blob = response.getBlob();
return blob;
}
Related
The email function works fine, but the code has the following error:
SyntaxError: Unexpected end of input (line 90, file "Code.gs") (last line) when the function checkValue was added.
Basically, we want the email to send automatically when D2 is edited. We are hoping this will eliminate the need to allow permissions to send email every time a template is copied by an aid.
function checkValue () {
var check = sheet.getRange("D2").getValue();
var rangeEdit =e.range.getA1Notation();
if(rangeEdit == "D2") {
{
function email(checkValue) {
// Send the PDF of the spreadsheet to this email address
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ClassA")
var lrow = sheet.getLastRow()
var name = sheet.getRange("E4").getValue();
var aid = sheet.getRange("E3").getValue();
var email = sheet.getRange("E5").getValue();
var pemail = sheet.getRange("E2").getValue();
var period = sheet.getRange("C1").getValue();
var og= sheet.getRange("D2").getValue();
// Subject of email message
var subject = "Grade Summary | " + og +"- " + period;
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "Hi " + name + ", "+ "<br><br> Please find the grade summary attached for " + period + ". <br><br> Let us know if you have any questions.<br><br> Thank you,<br><br> " + aid;
var aliases = GmailApp.getAliases()
Logger.log(aliases); //returns the list of aliases you own
Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
// Base URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=True' // orientation, false for landscape
+ '&fitw=true' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
//make an empty array to hold your fetched blobs
var blobs;
// Convert your specific sheet to blob
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs = response.getBlob().setName(sheet.getName() + '.pdf');
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
MailApp.sendEmail(email, subject, body, {
htmlBody: body,
name:'class',
bcc: aid,
noReply: true,
attachments:[blobs]
});
}
Basically, we want the email to send automatically when D2 is edited.
var rangeEdit =e.range.getA1Notation();
From what I see here it looks like you are trying to send an Email when the cell is changed, probably by using onEdit trigger.
You can't do that.
OnEdit belongs to simple triggers. Simple triggers can't call services that require authorization. Check here https://developers.google.com/apps-script/guides/triggers the Restrictions section.
If I'm wrong with what are you trying to do, please edit your post with the code, since "Carlos M" wrote in his reply that it can't compile.
Your code does not have enough closing brackets to terminate the function checkValue, thus it returns a syntax error.
Since your intent is to check the value first before sending the email, it is better if you separate the email function and call it from checkValue instead of enclosing it in an if statement. The parameter is not needed as well.
Also since you indicated that you need to send an email, you need an installable trigger. Create a trigger using the script service by running createSpreadsheetEditTrigger(), which will then run checkValue().
function createSpreadsheetEditTrigger() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ScriptApp.newTrigger('checkValue')
.forSpreadsheet(ss)
.onEdit()
.create();
}
function checkValue(e) {
var rangeEdit = e.range.getA1Notation();
if(rangeEdit == "D2") {
email();
}
}
function email() {
// Send the PDF of the spreadsheet to this email address
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("ClassA")
var lrow = sheet.getLastRow()
var name = sheet.getRange("E4").getValue();
var aid = sheet.getRange("E3").getValue();
var email = sheet.getRange("E5").getValue();
var pemail = sheet.getRange("E2").getValue();
var period = sheet.getRange("C1").getValue();
var og= sheet.getRange("D2").getValue();
// Subject of email message
var subject = "Grade Summary | " + og +"- " + period;
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "Hi " + name + ", "+ "<br><br> Please find the grade summary attached for " + period + ". <br><br> Let us know if you have any questions.<br><br> Thank you,<br><br> " + aid;
var aliases = GmailApp.getAliases()
Logger.log(aliases); //returns the list of aliases you own
Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
// Base URL
var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
/* Specify PDF export parameters
From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
*/
var url_ext = 'exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
+ '&size=letter' // paper size legal / letter / A4
+ '&portrait=True' // orientation, false for landscape
+ '&fitw=true' // fit to page width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid='; // the sheet's Id
var token = ScriptApp.getOAuthToken();
//make an empty array to hold your fetched blobs
var blobs;
// Convert your specific sheet to blob
var response = UrlFetchApp.fetch(url + url_ext + sheet.getSheetId(), {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs = response.getBlob().setName(sheet.getName() + '.pdf');
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
MailApp.sendEmail(email, subject, body, {
htmlBody: body,
name:'class',
bcc: aid,
noReply: true,
attachments:[blobs]
});
}
References:
Installable Triggers | Apps Script
I am trying to run an amazing script shared by Lauren Script for Google sheets (auto email function) and have an issue. I'm fairly new on stackoverflow so let me know if i need to ask this in another way if I'm breaking any norms? I have setup and successfully edited this script to do what i need it to do. I have a team that will be using this on mobile devices. I tried it and it did not work! can you help or point me in the right direction?
This is for a task list, when someone then selects a checkbox it sends any added notes and details to team leaders (and as per the script then unchecks the box). The checkbox is great as there is one per row. But open to any suggestions
Sorry for the lack of clarity, and thanks #TheMaster for helping out here. Code is below, but sounds like i am trying to do the impossible? Thought i would be able to do this with google sheets but it seems it is not possible on sheets android ap. I am not very advanced and might need to abandon the project! Any suggestions maybe even to do this in a different method?
function EmailNotification(e) {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Deliveries'); //source sheet
var columnb = sheet.getRange('J:J'); //Column with check boxes
var columnbvalue = columnb.getValues();
var notifysheet = ss.getSheetByName('Responses'); //destination sheet
var data = [];
var rownum =[];
//Condition check in B:B (or check box column); If true copy the same row to data array
for (i=0; i<columnbvalue.length;i++) {
if (columnbvalue[i] == 'true') {
var columnb2 = sheet.getRange('J2:J');
columnb2.setValue('false');
// What you want to say in the pop up alert
var response = ui.alert('Hold Up!\n Are you sure you want to send an email to team leaders for this delivery?', ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) {
data.push.apply(data,sheet.getRange(i+1,1,1,20).getValues());
//Copy matched ROW numbers to rownum
rownum.push(i);
//Copy data array to destination sheet
notifysheet.getRange(notifysheet.getLastRow()+1,1,data.length,data[0].length).setValues(data);
var activeRow = notifysheet.getLastRow();
var suppliername = notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var owner = notifysheet.getRange(activeRow, 3).getDisplayValue();
var recievedby = notifysheet.getRange(activeRow, 8).getDisplayValue();
var instructions = notifysheet.getRange(activeRow, 5).getDisplayValue();
var status = notifysheet.getRange(activeRow, 7).getDisplayValue();
var notes = notifysheet.getRange(activeRow, 9).getDisplayValue();
var email = notifysheet.getRange(activeRow, 4).getDisplayValue();
var subject = 'Delivery completed!'
//Body of the email message, using HTML and the variables from above
var message =
'<br><br><div style="margin-left:40px;">Hello '+ owner +'</div>'
+'<br><br><div style="margin-left:40px;">A delivery you requested has been fulfilled</div>'
+'<br><br><div style="margin-left:40px;"><h3 style="text-decoration: underline;">Recieved Name: '+ recievedby +'</h3></div>'
+'<div style="margin-left:40px;">Supplier: '+ suppliername +'</div>'
+'<div style="margin-left:40px;">Special instructions you added: '+ instructions +'</div>'
+'<div style="margin-left:40px;">Status: '+ status +'</div>'
+'<div style="margin-left:40px;">Notes: '+ notes +'</div>'
+ '<br><br><div style="margin-left:40px;">ヽ(⌐■_■)ノI Did It ♪♬</div>';
MailApp.sendEmail(
email,
subject,
"",
{
htmlBody: message,
name: 'Shop Alerts', //The name you want to email coming from
});
}
}
}
}
Mobile apps don't support ui or alerts. You just need to remove them.
function EmailNotification(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Deliveries'); //source sheet
var columnb = sheet.getRange('J:J'); //Column with check boxes
var columnbvalue = columnb.getValues();
var notifysheet = ss.getSheetByName('Responses'); //destination sheet
var data = [];
var rownum = [];
//Condition check in B:B (or check box column); If true copy the same row to data array
for (let i = 0; i < columnbvalue.length; i++) {
if (columnbvalue[i][0] === true) {
//modified to strict equality
var columnb2 = sheet.getRange('J2:J');
columnb2.setValue('false');
data.push.apply(data, sheet.getRange(i + 1, 1, 1, 20).getValues());
//Copy matched ROW numbers to rownum
rownum.push(i);
//Copy data array to destination sheet
notifysheet
.getRange(notifysheet.getLastRow() + 1, 1, data.length, data[0].length)
.setValues(data);
var activeRow = notifysheet.getLastRow();
var suppliername = notifysheet.getRange(activeRow, 1).getDisplayValue(); // The number is the column number in the destination "responses" sheet that you want to include in the email
var owner = notifysheet.getRange(activeRow, 3).getDisplayValue();
var recievedby = notifysheet.getRange(activeRow, 8).getDisplayValue();
var instructions = notifysheet.getRange(activeRow, 5).getDisplayValue();
var status = notifysheet.getRange(activeRow, 7).getDisplayValue();
var notes = notifysheet.getRange(activeRow, 9).getDisplayValue();
var email = notifysheet.getRange(activeRow, 4).getDisplayValue();
var subject = 'Delivery completed!';
//Body of the email message, using HTML and the variables from above
var message =
'<br><br><div style="margin-left:40px;">Hello ' +
owner +
'</div>' +
'<br><br><div style="margin-left:40px;">A delivery you requested has been fulfilled</div>' +
'<br><br><div style="margin-left:40px;"><h3 style="text-decoration: underline;">Recieved Name: ' +
recievedby +
'</h3></div>' +
'<div style="margin-left:40px;">Supplier: ' +
suppliername +
'</div>' +
'<div style="margin-left:40px;">Special instructions you added: ' +
instructions +
'</div>' +
'<div style="margin-left:40px;">Status: ' +
status +
'</div>' +
'<div style="margin-left:40px;">Notes: ' +
notes +
'</div>' +
'<br><br><div style="margin-left:40px;">ヽ(⌐■_■)ノI Did It ♪♬</div>';
MailApp.sendEmail(email, subject, '', {
htmlBody: message,
name: 'Shop Alerts', //The name you want to email coming from
});
}
}
}
The below script runs without any visible error, but no emails are sent. Any ideas as to why?
function sendEmailLoop() {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
sheets.forEach(function(sheet) {
var range = sheet.getDataRange();
if (sheet.getName() == "Summary") //Disregard tab named 'Summary'
{
}
else {
var range = sheet.getDataRange(); //to set the range as array
var values = range.getDisplayValues(); //to get the value in the array
var lastRow = range.getLastRow();
var ss = SpreadsheetApp.getActiveSpreadsheet(); //declare the spreadsheet
var sheet = ss.getSheetByName("Sheet1");
var Title = values[0][0]; //[Title] cell A1
var URL = values[0][1]; //[URL] cell B1
var i;
var logContent = '';
for (i = 3; i < lastRow; i++) {
var Name = values[i][0]; //[Name] cell A++
var Email = values[i][1]; // [Email] cell B++
Logger.log('to: ' + Email);
Logger.log('subject: ' + Name + Title + 'Test');
Logger.log('message: ' + 'This is a test message for the training that can be found at ' + URL);
/*
MailApp.sendEmail({
to: Email,
subject: Name + Title + 'Test',
message: 'This is a test message for the training that can be found at ' + URL});
*/
}; //end for loop - email tab data
}; // end 'else'
}); // end function(sheet)
} // end SendEmailLoop()
Here is the Stackdriver log of a successful execution (success meaning no errors, but still no emails are sent):
The structure of the spreadsheet associated with the script:
Note - an earlier version of this script didn't include the sheets.forEach() method call (ie, to loop through each tab of the spreadsheet) and the emails were sent fine.
Could the lack of emails being sent or received be related to the fact that I have many sheets and this function is looping through them?
function sendEmailLoop() {
var exclA=['Summary'];
var ss=SpreadsheetApp.getActive();
var sheets=ss.getSheets();
sheets.forEach(function(sheet) {
if (exclA.indexOf(sheet.getName())==-1) {
var range=sheet.getDataRange();
var values=range.getDisplayValues();
var lastRow=range.getLastRow();
var Title=values[0][0];
var URL=values[0][1];
var logContent='';
for (var i=3; i <values.length; i++) {
var Name=values[i][0];
var Email=values[i][1];
Logger.log('to: %s\nsubject: %s %s Test\nmessage: %s This is a test message for the training that can be found at %s',Email,Name,Title,URL);
/*
MailApp.sendEmail({
to: Email,
subject: Name + Title + 'Test',
message: 'This is a test message for the training that can be found at ' + URL});
*/
}
}
});
}
Answer:
You need to uncomment your MailApp code.
Code changes:
I tested your code and it seems to run without issue for me, including the receipt of the emails, only that the code comments around your MailApp call need to be removed (the /* and the */).
I would also suggest adding a conditional line before you send the email in the event .getDataRange() obtains seemingly empty rows:
if (Email == "") {
continue;
};
MailApp.sendEmail({
to: Email,
subject: Name + Title + 'Test',
message: 'This is a test message for the training that can be found at ' + URL});
References:
JavaScript Comments
Background: I am a teacher. I gave a test through Forms. I graded the test by using various background colors on each cell (which represented an answer to a question by a student). Each row of the sheet has their email address in Column B.
Problem: I would like to email the entire row, including formatting, to that address in Column B so that each student has a record of their answers and how I graded them.
Question: How can I email a row of data, including formatting?
I am working with the following script, which works well for emailing a single cell without formatting:
`function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
// Fetch the range of cells A2:B3
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[1]; // Second column
var message = row[0]; // I want the whole row, including formatting.
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
ContentService.createTextOutput("hello world!");
}
}`
Here it is.
I decided to add another function as it makes it a little cleaner. You'll be able to adjust the styles of the output by playing with the css styles. If you keep the commented lines your can use them for debugging. I tested the code with them and it looks good. So let me know how it works on the emails.
function sendEmails()
{
var br='<br />';
var sheet=SpreadsheetApp.getActiveSheet();
var dataRange=sheet.getDataRange();
var dataA=dataRange.getValues();
var backA=dataRange.getBackgrounds();
//var s='';//Please leave the commented lines. If needed for the future they are handy to have
for (var i=1;i<dataA.length;i++)
{
var emailAddress=dataA[i][1];
var message=formatRow(sheet.getName(),dataA[i],backA[i],dataA[0]);
var subject="Sending emails from a Spreadsheet";
//s+=br + '<strong>EmailAddress:</strong>' + emailAddress + br + '<strong>Subject:</strong>' + subject + br + message + '**************************************' + br;
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:message});
}
//var userInterface=HtmlService.createHtmlOutput(s);
//SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Email Message')
}
I just noticed the yellow background so I quickly added another section for it.
//assume Timestamp,EmailAddres,Score,FirstName,LastName,Section...
function formatRow(sheetName,rowA,rowbackA,titleA)
{
var br='<br />';
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName(sheetName);
var html='';
if(rowA && rowbackA)
{
html='';
for(var j=0;j<rowA.length;j++)
{
switch(rowbackA[j])
{
case '#ff0000':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ff0000;">' + rowA[j] + '</span>' + br;
break;
case '#ffff00':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ffff00;">' + rowA[j] + '</span>' + br;
break;
case '#ffffff':
html+=br + '<span style="font-weight:600;font-size:20px;">' + titleA[j] + ':</span>' + br + '<span style="background-color:#ffffff;">' + rowA[j] + '</span>' + br;
break
}
}
}
return html;
}
Just a reminder I'm using #ff0000 for red so don't change to a different shade without making a change to the code.
In the event that one student's email gets eaten by the dog, you might like to send just one email.
function sendOneEmail(firstName,lastName)
{
if(firstName && lastName)
{
var br='<br />';
var sheet=SpreadsheetApp.getActiveSheet();
var dataRange=sheet.getDataRange();
var dataA=dataRange.getValues();
var backA=dataRange.getBackgrounds();
//var s='';//Please leave the commented lines. If needed for the future they are handy to have
for (var i=1;i<dataA.length;i++)
{
if(firstName==dataA[i][3] && lastName==dataA[i][4])
{
var emailAddress=dataA[i][1];
var message=formatRow(sheet.getName(),dataA[i],backA[i],dataA[0]);
var subject="Sending emails from a Spreadsheet";
//s+=br + '<strong>EmailAddress:</strong>' + emailAddress + br + '<strong>Subject:</strong>' + subject + br + message + '**************************************' + br;
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:message});
}
}
//var userInterface=HtmlService.createHtmlOutput(s);
//SpreadsheetApp.getUi().showModelessDialog(userInterface, 'Email Message')
}
}
Here's a birds eye view of the Spreadsheet.
So I'm working on a project in Google Sheets, using scripting, that will eventually do the following;
Firstly, based on a name in a Cell , find the last 9 entries for that person in form responses.
It then arranges that data in a way that I need and writes it to a sheet, within my spreadsheet
The last part of the script (not my own work, but something i found here)
Script I found online
I've tried to adapt for my needs, not quite there yet. Creates a PDF, saves it in google drive then emails it.
This part requires a bit more work, as I want to specify what the PDF is called using the name and date. Also I'd like to specify where it's saved in google. Lastly the script only produces one PDF. Would like to eventually duplicate the script so I can either create 1 PDF or create them in batches. Will possibly post about these later, if I get stuck.
So anyways that is the overview.
Currently the script works and can query the data I want, write it to a sheet, save it to drive as PDF and email it to a single hard-coded email address. Awesomeness.
But I then tried to add a function called clearRanges which would clear out the template sheet before writing data. I used name ranges to define the 3 sections to clear. But since introducing it, and i've tried it in various parts of my script. I'm getting blank PDF's in my drive and by email.
It's like it's not waiting for the PDF to be created or email to be sent before clearing data. I've tried to put it at the start of my script too, but same thing. Got no idea why.
I was playing around with lock and waitlock as a possible solution, but it didn't seem to help.
If anyone can help out, I'd appreciate it.
function getAgentName() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
Browser.msgBox("Please go to the sheet called PDF Creator, in cell A2, choose the agent you wish to create a PDF for");
var sheet = ss.getSheetByName("PDF Creator");
var range = sheet.getRange("A2")
var value = range.getValue();
if (value == 0) {
Browser.msgBox("You need to go to the sheet named PDF Creator and put an agent name in cell A2");
} else {
getAgentData(value);
}
}
function getAgentData(value) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("Form responses 1")
var sourceRange = sourceSheet.getDataRange();
var sourceValues = sourceRange.getValues();
var agentData = [];
var commentsData = [];
for (i = 0; i < sourceValues.length; i++) {
// Defines the data layout for PDF.
var agentName = sourceValues[i][2];
var dateTime = sourceValues[i][3];
var callType = sourceValues[i][7];
var opening = sourceValues[i][8];
var rootCause = sourceValues[i][9];
var rootFix = sourceValues[i][10];
var process = sourceValues[i][11];
var consumer = sourceValues[i][12];
var control = sourceValues[i][13];
var wrapup = sourceValues[i][14];
var dpa = sourceValues[i][15];
var score = sourceValues[i][22];
var comments = sourceValues[i][16];
var agentRow = [dateTime, callType, opening, rootCause, rootFix, process, consumer, control, wrapup, dpa, score];
var commentsRow = [dateTime, comments];
if (agentName == value && agentData.length < 9) {
agentData.push(agentRow)
commentsData.push(commentsRow)
}
}
agentData.sort(function (a, b) {
return b[0] - a[0]
});
commentsData.sort(function (a, b) {
return b[0] - a[0]
});
var destSheet = ss.getSheetByName("AgentPDF");
destSheet.getRange("A1").setValue(value + "'s Quality Score card");
var range = destSheet.getRange(6, 1, agentData.length, agentData[0].length);
range.setValues(agentData);
var commentRange = destSheet.getRange(18, 1, commentsData.length, commentsData[0].length);
commentRange.setValues(commentsData);
emailSpreadsheetAsPDF();
}
/* Send Spreadsheet in an email as PDF, automatically */
function emailSpreadsheetAsPDF() {
// Send the PDF of the spreadsheet to this email address
var email = "firstname.lastname#domain.co.uk";
// Subject of email message
// The date time string can be formatted in your timezone using Utilities.formatDate method
var subject = "PDF Reports - " + (new Date()).toString();
// Get the currently active spreadsheet URL (link)
// Or use SpreadsheetApp.openByUrl("<<SPREADSHEET URL>>");
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Email Body can be HTML too with your logo image - see ctrlq.org/html-mail
var body = "PDF generated using code at ctrlq.org from sheet " + ss.getName();
var url = ss.getUrl();
url = url.replace(/edit$/, '');
/* Specify PDF export parameters
// From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
exportFormat = pdf / csv / xls / xlsx
gridlines = true / false
printtitle = true (1) / false (0)
size = legal / letter/ A4
fzr (repeat frozen rows) = true / false
portrait = true (1) / false (0)
fitw (fit to page width) = true (1) / false (0)
add gid if to export a particular sheet - 0, 1, 2,..
*/
var url_ext = 'export?exportFormat=pdf&format=pdf' // export as pdf
+ '&size=a4' // paper size
+ '&portrait=1' // orientation, false for landscape
+ '&fitw=true&source=labnol' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false' // hide optional headers and footers
+ '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
+ '&fzr=false' // do not repeat row headers (frozen rows) on each page
+ '&gid=928916939'; // the sheet's Id
var token = ScriptApp.getOAuthToken();
// var sheets = ss.getSheets();
//make an empty array to hold your fetched blobs
var blobs = [];
// for (var i=0; i<sheets.length; i++) {
// Convert individual worksheets to PDF
// var response = UrlFetchApp.fetch(url + url_ext + sheets[i].getSheetId(), {
var response = UrlFetchApp.fetch(url + url_ext, {
headers: {
'Authorization': 'Bearer ' + token
}
});
//convert the response to a blob and store in our array
blobs[0] = response.getBlob().setName("Tester " + '.pdf');
// }
//create new blob that is a zip file containing our blob array
// var zipBlob = Utilities.zip(blobs).setName(ss.getName() + '.zip');
var test = DriveApp.createFile(blobs[0]);
//optional: save the file to the root folder of Google Drive
DriveApp.createFile(test);
// Define the scope
Logger.log("Storage Space used: " + DriveApp.getStorageUsed());
// If allowed to send emails, send the email with the PDF attachment
if (MailApp.getRemainingDailyQuota() > 0)
var lock = LockService.getScriptLock();
GmailApp.sendEmail(email, subject, body, {
attachments: [test]
});
lock.waitLock(20000);
lock.releaseLock();
clearRanges();
}
function clearRanges() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getRangeByName('Header').clearContent();
ss.getRangeByName('Scores').clearContent();
ss.getRangeByName('Comments').clearContent();
}
Can you try adding SpreadsheetApp.flush();
around line 60 before calling emailSpreadsheetAsPDF();
SpreadsheetApp.flush()
commentRange.setValues(commentsData);
SpreadsheetApp.flush();
emailSpreadsheetAsPDF();
I've faced a similar problem before and this worked.