首页 > 解决方案 > 在谷歌表格中发送电子邮件后出现 onEdit 问题

问题描述

这是我在谷歌脚本中的代码:

function Send(){
Browser.msgBox("Send");
   }

function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var startRow = 2;
  var lr = sheet.getLastRow();

  var dataRange = sheet.getRange(startRow, 1, lr-1, 6);

  var data = dataRange.getValues();

  for (var i = 0; i < data.length; i++) {
    var row = data[i];
    var name = row[0];
    var emailAddress = row[1];
    var date = row[2];
    var city = row[3];
     var status = row[6];
    
    if (emailAddress.match('@')  === null){
   continue;
    };

    var subject = row[4];
    var message = "Hey " + name + ", welcome in the team " + row[5];

    MailApp.sendEmail(emailAddress, subject, message);

    sheet.getRange(i+2,7).setValue("Sent");
      }
}

直到这里一切正常。我希望当“已发送”出现在第 7 列时,将“已发送”所在的整行移动到另一个选项卡。

function onEdit(e) {
  var ss = e.source;
  var s = ss.getActiveSheet();
  var r = e.range;
  var actionCol = 7;
  var nameCol = 7;
  var rowIndex = r.getRowIndex();
  var colIndex = r.getColumnIndex();
  var colNumber = s.getLastColumn()-1;
  if (e.value == "Sent" && colIndex == actionCol) {
       var targetSheet = s.getRange(rowIndex, nameCol).getValue();
       if (ss.getSheetByName("Welcome")) { 
           var targetSheet = ss.getSheetByName("Done");
      var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
       var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
        sourceRange.copyTo(targetRange);
            s.deleteRow(rowIndex);
          }
  }
}

**如果我在第 7 列手动写“已发送”,则该行将移至另一张表。但是当我运行第一个函数并且“已发送”出现在该列中时,onEdit 函数不起作用。所以基本上这两个功能都可以工作,但不能同时使用。

有人知道解决这个问题吗?**

标签: functiongoogle-apps-scriptgoogle-sheets

解决方案


问题:

  • 您正在尝试onEdit通过脚本触发函数,但这不是触发器的工作方式。官方文档声明如下:

onEdit(e)用户更改电子表格中任何单元格的值时,触发器会自动运行。

也就是说,onEdit触发器仅由用户操作激活,而不是由脚本或公式激活。

  • 您不需要单独的函数来检查该值是否为Sent,然后使用另一个函数删除该行。发送电子邮件后,您可以移动数据并删除行,所有这些都在同一个功能中。

  • 最后但同样重要的是,当迭代删除行时,我们会更改工作表的结构,因此数据输入与更新后的结构不匹配。为了缓解这个问题,我们可以将要删除的行的索引存储在一个数组中,然后使用该数组向后删除行。

解决方案:

假设您的代码单独工作,这也应该工作:

function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Welcome");
  var targetSheet = ss.getSheetByName("Done");
  var startRow = 2;
  var lr = sheet.getLastRow();
  var dataRange = sheet.getRange(startRow, 1, lr-1, 6);
  var data = dataRange.getValues(); 
  var colNumber = sheet.getLastColumn()-1;
  var delRows = [];
  for (var i = 0; i < data.length; i++) {
      var row = data[i];
      var name = row[0];
      var emailAddress = row[1];
      var date = row[2];
      var city = row[3];
      var status = row[6];
      if (emailAddress.match('@')  === null){
         continue;
      };
      var subject = row[4];
      var message = "Hey " + name + ", welcome in the team " + row[5];
      MailApp.sendEmail(emailAddress, subject, message);
      var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
      var sourceRange = sheet.getRange(i+startRow, 1, 1, colNumber);
      sourceRange.copyTo(targetRange);
      delRows.push(i+startRow); 
      }   
  // delete rows in reverse order    
  delRows.reverse().forEach(ri=>{sheet.deleteRow(ri)});  
}

您不再需要该onEdit功能,因此可以将其删除。


推荐阅读