Complete Email Sending and Archiving Example
Here's a complete example I just did recently. I thought it was time for me to learn a little about sending emails from a spreadsheet since we get questions like this a lot. Now in your case you want to do for different sheets so I added a parameter to my sendingMyEmails() function. So that now it's sendingMyEmails(sheetname). You have to add either separate function calls for each sheet like below:
function sendEmailsSheet1()
{
sendingMyEmails('Sheet1');
}
Or you could do something like this:
function sendAllSheets()
{
var sheets=['Sheet1','Sheet2','Sheet3','Sheet4']
for(var i=0;i<sheets.length;i++)
{
sendMyEmails(sheets[i]);
}
}
Either way you only need one function for sending all of the emails in each sheet. This example also includes the capability to archive your emails to an emailSent tab. I collect all that information and then display it as an HTML Dialog which allows you to check off which emails you wish to have archived.
SendingEmails.gs
function sendingMyEmails(sheetname)
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName(sheetname);
var rng=sht.getDataRange();
var rngA=rng.getValues();
var s='<html><head><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script></head><body>';
var someNotSent=false;
for(var i=2;i<rngA.length;i++)
{
var dataA={};
for(var j=0;j<rngA[1].length;j++)
{
dataA[rngA[1][j]]=rngA[i][j];
}
if(dataA.EntryDate && dataA.Name && dataA.Email && dataA.Subject && dataA.Body && dataA.SendIfYes=='Yes' && dataA.DateSent=='')
{
MailApp.sendEmail(dataA.Email, dataA.Subject, dataA.Body, {replyTo:dataA.Sender});
sht.getRange(i+1,8).setValue(Utilities.formatDate(new Date(), 'GMT-6', "M/dd/yyyy'\n'HH:mm:ss"));
SpreadsheetApp.flush();
}
else
{
var row=Number(i+1);
s+='<div id="row' + row + '"><input type="checkbox" name="email" value="' + Number(i+1) + '" />' + 'Email Not Sent: <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Email:</strong> ' + dataA.Email + ' <strong>Subject:</strong> ' + dataA.Subject + ' <strong>EntryDate:</strong> ' + dataA.EntryDate + '</div>';
someNotSent=true;
}
}
if(someNotSent)
{
s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Archive Checked" onClick="getCheckedBoxes(\'email\');" />';
s+='</body></html>';
var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
html.append(s);
SpreadsheetApp.getUi().showModelessDialog(html, 'Emails Not Sent');
}
}
function archiveSelectedEmails()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('EmailSetup');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var s='<html><head><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script></head><body>';
var s='';
for(var i=2;i<rngA.length;i++)
{
var dataA={};
for(var j=0;j<rngA[1].length;j++)
{
dataA[rngA[1][j]]=rngA[i][j];
}
var row=Number(i+1);
s+='<div id="row' + row + '"><input type="checkbox" name="email" value="' + Number(i+1) + '" />' + ' <strong>Row:</strong> ' + Number(i+1) + ' <strong>Name:</strong> ' + dataA.Name + ' <strong>Email:</strong> ' + dataA.Email + ' <strong>Subject:</strong> ' + dataA.Subject + ' <strong>DateSent:</strong> ' + Utilities.formatDate(new Date(dataA.DateSent), 'GMT-6', "M/dd/yyyy HH:mm:ss") + '</div>';
}
s+='<br /><input type="button" value="Exit" onClick="google.script.host.close();" /><input type="button" value="Archive Checked" onClick="getCheckedBoxes(\'email\');" />';
var html=HtmlService.createHtmlOutputFromFile('htmlToBody').setWidth(800).setHeight(250);
html.append(s);
SpreadsheetApp.getUi().showModelessDialog(html, 'Select Emails to Archive');
}
function test()
{
var rows=[3];
archiveSelectedRows(rows);
}
function archiveSelectedRows(rows,sheetname)
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName(sheetname);
var dest=ss.getSheetByName('EmailsSent');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var deleted=[];
for(var i=rngA.length-1;i>1;i--)
{
if(rows.indexOf(i+1)>-1)
{
deleted.push(Number(i+1));
dest.appendRow(rngA[i]);
sht.deleteRow(i+1);
}
}
var msg='Rows Deleted = ' + deleted;
var title='Rows Deleted';
var timeout=10;
return deleted;
}
Sample Sheet
This is an image of the header rows for my emailSetup sheet and the emailsSent sheet has the same columns. I don't use a dialog to identify the emails that are already sent so that I can archive them away on another sheet.
htmlToBody.html
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var rowsToArchive = [];
for (var i=0; i<checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
rowsToArchive.push(Number(checkboxes[i].value));
}
}
google.script.run
.withSuccessHandler(setResponse)
.archiveSelectedRows(rowsToArchive);
}
function setResponse(a)
{
var s='<br />Rows: ';
for(var i=0;i<a.length;i++)
{
if(i>0)
{
s+=', ';
}
s+=a[i];
var id='#row' + a[i]
$(id).css('display','none');
}
s+='<br />Total: ' + a.length;
google.script.run.displayMessage(s,'Archived Rows')
}
console.log('script here');
</script>
</head>
<body>
Utility.gs
function displayToast(msg,title,timeoutSeconds)
{
SpreadsheetApp.getActiveSpreadsheet().toast(msg, title, timeoutSeconds)
}
function displayMessage(msg,title)
{
msg+='<br /><input type="button" value="Exit" onClick="google.script.host.close()"; />';
var html=HtmlService.createHtmlOutput(msg).setWidth(400).setHeight(300);
SpreadsheetApp.getUi().showModelessDialog(html, title);
}
Code.gs
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Send Emails','sendingMyEmails')
.addItem('Archive Selected Emails','archiveSelectedEmails')
.addToUi();
}