title: Picking up where the script ended when time limit is reached
body: <p>I'm trying to implement the solution that Anton Soradoi proposed on 12/22/11 to enable a mail merge script that will exceed its maximum execution time terminate gracefully, wait a period of time, then pick up where it left off and continue doing so until its run is complete. <a href="https://stackoverflow.com/questions/7854573/exceeded-maximum-execution-time-in-google-apps-script">Here</a> is the link to the referenced post.</p>
  
  <p>The script runs fine for the aloted time (5 min), then throws a "Execution failed: Invalid argument: value (line 80). Also, I'm not sure what the "else" part of the script that Anton Soradoi discussed is supposed to do (run my menuItem1 function again?). I feel like I'm pretty close, and any help would be greatly appreciated. My code is below:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>//Creates the custom menu in the spreadsheet "Run Script"
  function onOpen() {
    var ui = SpreadsheetApp.getUi();
    ui.createMenu('Script')
        .addItem('Create Certs', 'menuItem1')
        .addToUi();
  }//Ends the custom menu in the spreadsheet
  
  //Runs the menuItem 1 operation (Create Certs)
  function menuItem1() {
  //Defines the start row and calculates the number of rows to be processed
    var sheet = SpreadsheetApp.getActiveSheet();
    var startRow = Browser.inputBox("Enter Start Row");
    var endRow = Browser.inputBox("Enter End Row");
    var numRows = (endRow - startRow) + 1; //this is the row height
    var dataRange = sheet.getRange(startRow, 1, numRows, 7);
    var counter =0;   
    var data = dataRange.getValues();   
    var templateDoc = DriveApp.getFileById("1baxSUxfSdzcVheR3Y2qgieWeSAqNybPfWct1913uRIc");   
    var templateCopy = templateDoc.makeCopy();
    var templateCopyId = templateCopy.getId();
    var dateOld;   
    var courseOld;   
    var fullNameOld;
    var mailFrom = GmailApp.getAliases()
    var team = "NWC Online PME Help Desk"
    var startTime= (new Date()).getTime();
    
  for (var i = 0; i &lt; data.length; ++i) {
          var doc = DocumentApp.openById(templateCopyId);
          var body = doc.getActiveSection();
          var row = data[i];
          var date = row[0];
          var nic = row[1];
          var course = row[2];
          var lastname = row[3];
          var firstname = row[4];
          var middle = row[5]
          var email = row[6];
          var subjectTxt = "NWC Online PME Course Certificate";
          var fullBody = "PME COURSE COMPLETION CERTIFICATE" + "\n\n";
             fullBody += "Your course completion certificate is attached." + "\n\n";
             fullBody += "NOTES:" + "\n";
             fullBody += "1. DO NOT telephone NWC to resolve PME certificate issues, email our Help Desk: pmecerthelp@usnwc.edu." + "\n";
             fullBody += "2. NWC does NOT mail hardcopy certificates." + "\n";
             fullBody += "3. NWC does not award certificates for the SNCO JPME courses." + "\n";
             fullBody += "4. NWC course completion certificates are not automatically entered into your electronic training or service records." + "\n\n";
             fullBody += "Regards," + "\n\n";
             fullBody += "U.S. Naval War College Online PME Program Team"+ "\n\n";
             fullBody += "Learn more about NWC's Online PME Program at the link below:" + "\n";
             fullBody += "http://www.usnwc.edu/Academics/College-of-Distance-Education/PME-(1).aspx" + "\n";
          var fullName = firstname+' '+middle+''+lastname
          var fdate = Utilities.formatDate(new Date(date), "UTC", "d MMMM yyyy"); //converts UTC date
             if(counter ==0){
               body.replaceText('fullName',fullName);  
               body.replaceText('course', course);
               body.replaceText('date', fdate); 
          }//Ends the if condition
             else {   
               body.replaceText(fullNameOld,fullName);
               body.replaceText(courseOld, course);
               body.replaceText(dateOld, fdate); 
          }//Ends the else condition
             dateOld = fdate; 
             courseOld = course;
             fullNameOld = fullName;
             counter ++
  
     doc.saveAndClose();
        var attachment = doc.getAs('application/pdf');
        GmailApp.sendEmail(email, subjectTxt, fullBody, {name: team, attachments: attachment, from: mailFrom[1]});
   
        var scriptProperties = PropertiesService.getScriptProperties();
        var newStartRow= scriptProperties.getProperty('row');
  
     for(var ii = newStartRow; ii &lt;= data.length; ii++) {
        var currTime = (new Date()).getTime();
      
      if(currTime - startTime &gt;= 300000) {
        scriptProperties.setProperty("row", ii);
        ScriptApp.newTrigger("menuItem1")
                 .timeBased()
                 .at(new Date(currTime+30000))
                 .create();
        break;
      }//Ends the if loop
    }//Ends the second for loop
  
     }//Ends the first for loop 
  }//Ends menuItem1</code></pre>
  </div>
  </div>
  </p>