优化Google Script for循环

时间:2018-03-07 20:36:44

标签: caching optimization google-apps-script

我有一个应用程序脚本循环遍历个人列表,然后遍历数据表并将列表中每个人的电子邮件放在一起,并向他们发送个性化电子邮件。但是,我目前遇到的问题是脚本对于我拥有的个人数量来说太慢了,我最终得到了运行时错误。

无论如何都要优化代码?我开始考虑缓存数据,这样我就不会经常打电话给电子表格,但说实话,这对我来说都是新手,所以我不知道从哪里开始。

请注意,我正在使用Google表格中的2个标签。第一个包含名称和电子邮件地址,第二个是包含数据的15列表。

这是我目前的代码:

function BM_Emails() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataRange = ss.getSheetByName("BM E-mail Data").getDataRange();
  var emailRange = ss.getSheetByName("BM E-mail List").getDataRange();
  var shBody = ss.getSheetByName("E-mail Body");
  var data = dataRange.getValues();
  var nameData = emailRange.getValues();
  var lastCol = dataRange.getLastColumn();
  var lastRow = emailRange.getLastRow();
  var bottEmail = shBody.getRange("A12").getValue();

  for (var i = 1; i < nameData.length; i++) {
    var rows = nameData[i];
    var emailAddress = rows[2]; 
    var empID = rows[1]; 
    var firstName = rows[3] 
    var bmLOS = rows[0] 
    var subject = "Action Requested: Overdue";
    var htmltable = "";
    var htmlmessage = "";
    var pre_table = '<!DOCTYPE html><html>' + firstName + ',<br>';
    var post_table = '</html>';

    for (row = 0; row < data.length; row++) {
      for (col = 1; col < data[row].length; col++) {
        if (row == 0 && col == 1) {
            htmltable += '<tr><th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th>';
        } else
        if (row == 0 && col == lastCol - 1) {
            htmltable += '<th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th></tr>';
        } else
        if (row == 0) {
            htmltable += '<th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th>';
        } else
        if (data[row][0] == empID && col == 1) {
            htmltable += '<tr><td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td>';
        } else
        if (data[row][0] == empID && col == lastCol - 1) {
            htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td></tr>';
        } else
        if (data[row][0] == empID && (col == 5 || col == 6)) {
            htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + formatCurrency('$', data[row][col]) + '</td>';
        } else
        if (data[row][0] == empID && col == 7) {
            htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + Utilities.formatDate(data[row][col], "GMT", "MM-dd-yy") + '</td>';
        } else
        if (data[row][0] == empID) {
            htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td>';
        }
      }
    }

    htmltable += '</tbody></table>';
    htmlmessage = pre_table + htmltable + bottEmail + post_table;

    GmailApp.sendEmail(emailAddress, subject, '', {
      htmlBody: htmlmessage
    });
  };
}

1 个答案:

答案 0 :(得分:0)

你有三个嵌套循环。没有数据,很难确认所有这三个是必要的或证明这解决了超时问题 - 但是在控制进入你的控制之前,通过实现 row 的条件,它确实可以优化最后两个循环中的代码循环 col 。当 row 不是标题或 empID 所需的行时,这将减少通过 col 的不必要的循环。

似乎值得尝试的可能的优化步骤。

function BM_Emails() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataRange = ss.getSheetByName("BM E-mail Data").getDataRange();
  var emailRange = ss.getSheetByName("BM E-mail List").getDataRange();
  var shBody = ss.getSheetByName("E-mail Body");
  var data = dataRange.getValues();
  var nameData = emailRange.getValues();
  var lastCol = dataRange.getLastColumn();
  var lastRow = emailRange.getLastRow();
  var bottEmail = shBody.getRange("A12").getValue();

  for (var i = 1; i < nameData.length; i++) {
    var rows = nameData[i];
    var emailAddress = rows[2]; 
    var empID = rows[1]; 
    var firstName = rows[3] 
    var bmLOS = rows[0] 
    var subject = "Action Requested: Overdue";
    var htmltable = "";
    var htmlmessage = "";
    var pre_table = '<!DOCTYPE html><html>' + firstName + ',<br>';
    var post_table = '</html>';

    for (row = 0; row < data.length; row++) {
      if (row == 0){// changed to ==<----------------------------------HERE
        for (col = 1; col < data[row].length; col++) {
          if (col == 1) {
              htmltable += '<tr><th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th>';
          } else
          if (col == lastCol - 1) {
              htmltable += '<th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th></tr>';
          } else {
              htmltable += '<th style="border-collapse: collapse;border: 1px solid black;background-color:#D5D8DC">' + data[row][col] + '</th>';  
          }
        }      
      }
      else if (data[row][0] == empID) {// removed ( after [0]<---------HERE
        for (col = 1; col < data[row].length; col++) {
          if (col == 1) {
              htmltable += '<tr><td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td>';
          } else
          if (col == lastCol - 1) {
              htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td></tr>';
          } else
          if (col == 5 || col == 6) {
              htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + formatCurrency('$', data[row][col]) + '</td>';
          } else
          if (col == 7) {
              htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + Utilities.formatDate(data[row][col], "GMT", "MM-dd-yy") + '</td>';
          } else {
              htmltable += '<td style="border-collapse: collapse;border: 1px solid black">' + data[row][col] + '</td>';
          }
        }  
      }
    }

    htmltable += '</tbody></table>';
    htmlmessage = pre_table + htmltable + bottEmail + post_table;

    GmailApp.sendEmail(emailAddress, subject, '', {
      htmlBody: htmlmessage
    });
  };
}