0
votes

I have found a few threads with how to update the script but I cant get it to work with the limit knowledge I have with Scripts

I have upto about 6 Tabs ,Sheet1,Sheet2,Sheet3,Sheet4,Sheet5,Sheet6 that I want to send emails up of but at this stage it only looks at the first sheet. Can someone let me know how to update this please

Thanks Jarrad

function sendEmails() {
   var sheet = SpreadsheetApp.getActiveSheet();
   var range = sheet.getRange(1, 2);  // Fetch the range of cells B1:B1
   var subject = range.getValues();   // Fetch value for subject line from above range
   var range = sheet.getRange(1, 9);  // Fetch the range of cells I1:I1
   var numRows = range.getValues();   // Fetch value for number of emails from above range
   var startRow = 4;                  // First row of data to process
   var dataRange = sheet.getRange(startRow, 1, numRows,9 ) // Fetch the range of cells A4:I_
   var data = dataRange.getValues();  // Fetch values for each row in the Range.
   for (i in data) {
      var row = data[i];
      var emailAddress = row[1];      // Second column
      var message = row[8];           // Ninth column
      MailApp.sendEmail(emailAddress, subject, message);
   }
}

Hi Cooper thanks for the info but im only just starting out with scripts I want to start with the basics for now and ill work out form there. I cant picture wan you are saying I know its simple info but I cant work it out just yet. Do I remove this line var sheet = SpreadsheetApp.getActiveSheet(); and replace with. I get errors on line var range line. I need to see it in full to try and understand what Im looking at. Sorry for the basic question

var sheets=['Sheet1','Sheet2','Sheet3','Sheet4']
  for(var i=0;i<sheets.length;i++)



function sendEmails() {
   var sheet = SpreadsheetApp.getActiveSheet();
   var range = sheet.getRange(1, 2);  // Fetch the range of cells B1:B1
   var subject = range.getValues();   // Fetch value for subject line from above range
   var range = sheet.getRange(1, 9);  // Fetch the range of cells I1:I1
   var numRows = range.getValues();   // Fetch value for number of emails from above range
   var startRow = 4;                  // First row of data to process
   var dataRange = sheet.getRange(startRow, 1, numRows,9 ) // Fetch the range of cells A4:I_
   var data = dataRange.getValues();  // Fetch values for each row in the Range.
   for (i in data) {
      var row = data[i];
      var emailAddress = row[1];      // Second column
      var message = row[8];           // Ninth column
      MailApp.sendEmail(emailAddress, subject, message);
2
Can you share your spreadsheet?Cooper

2 Answers

1
votes

You'll probably want to use something like this

function sendEmails()
{
  var mySheets=['Telstra out of date','Optus out of date','Vodafone out of date','Drivers Licence out of date'];
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  var allSheets=ss.getSheets();
  for(var i=0;i<allSheets.length;i++)
  { 
    var sht=allSheets[i]; 
    if(mySheets.indexOf(sht.getName())>-1)//if you have sheets you don't want to send emails from
    {
      var rng=sht.getDataRange();
      var rngA=rng.getValues();
      var subject = rngA[0][1];//B1
      for(var j=3;j<rngA.length;j++)//start row was 4
      {
        var emailAddress = rngA[j][1];//col 2
        var message = String(rngA[3][2]) + String(rngA[j][3]);//col 3
        if(emailAddress)
        {
          MailApp.sendEmail(emailAddress, subject, message);
          //Logger.log('EmailAddress: ' + emailAddress + ' Subject: ' + subject + ' Message: ' + message);
        }
      }
    }
  }
}
1
votes

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. enter image description here

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();

}