如果具有值触发器的行中的任何单元格已更新,则sendNotification继续发送电子邮件

时间:2018-10-22 18:42:50

标签: javascript google-apps-script google-sheets

当列“ G”的值为“所有要DC的组件”时,我正在使用sendNotification触发电子邮件。但是,我遇到的问题是,当该列已经具有数据“ DC的所有组件”并且同一行中的另一列已更新(使用任何值)时,脚本再次检查“ G”列并看到“ DC的所有组件”,然后重新发送同一封电子邮件。

将如何重新编写脚本,以便仅在更新列“ G”并且忽略同一行中的其他单元格时才发送通知?

function sendNotification(e){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var cell = ss.getActiveCell().getA1Notation();
  var row = sheet.getActiveRange().getRow();
  var cellvalue = ss.getActiveCell().getDisplayValue().toString();

  if(sheet.getRange('G'+row).getValue()=='All Components at DC')
  {
    var recipients = "xxx@xxx.com";
    var subject = "Delivered Items"
    var message = sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue() + '\n TITLE: ' + sheet.getRange('F'+ sheet.getActiveCell().getRowIndex()).getValue() + '\n LANGUAGE: ' + sheet.getRange('E'+ sheet.getActiveCell().getRowIndex()).getValue()
    var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + '\n ROW: ' + row + '\n DATE: ' + message + '\n COMMENT: ' + cellvalue;
    var valColB=e.range.getSheet().getRange(e.range.getRow(),2).getValue();
    MailApp.sendEmail(recipients, subject, body);
  }
}

1 个答案:

答案 0 :(得分:0)

这个答案怎么样?

  • sendNotification()已安装为OnEdit的可安装触发器。
  • 您只想在列“ G”的单元格更新时运行sendNotification()

如果我对您的情况的理解是正确的,那么如何进行修改?

发件人:

if(sheet.getRange('G'+row).getValue()=='All Components at DC')

收件人:

if(cell[0] == 'G' && sheet.getRange('G'+row).getValue()=='All Components at DC')

在此修改中,仅当通过添加if编辑了“ G”列时,才运行cell[0] == 'G'中的脚本。

作为另一个修改,您还可以使用OnEdit的事件对象。以下示例脚本使用事件对象。使用事件对象时,可以减少处理成本。

使用事件对象的示例脚本:

function sendNotification(e) {
  var ss = e.source;
  var sheet = ss.getActiveSheet();
  var range = e.range;
  var values = range.offset(0, -6, 1, 6).getValues()[0];
  var activeCell = range.getValue();
  if (range.getA1Notation()[0] == 'G' && activeCell == 'All Components at DC') {
    var recipients = "xxx@xxx.com";
    var subject = "Delivered Items";
    var message = values[0] + '\n TITLE: ' + values[5] + '\n LANGUAGE: ' + values[4];
    var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + '\n ROW: ' + range.getRow() + '\n DATE: ' + message + '\n COMMENT: ' + activeCell;
    var valColB=e.range.getSheet().getRange(e.range.getRow(),2).getValue();
    MailApp.sendEmail(recipients, subject, body);
  }
}

参考文献:

如果这不是您想要的,请告诉我。我想修改它。

编辑:

关于这种情况的问题:

事件对象具有已编辑单元格的旧值。但是在您的情况下,用作触发器的单元格不是已编辑的单元格。例如,在列“ I”至“ L”具有值Delivered to DC的条件下,当将Delivered to DC放入列“ M”且列“ G”的值从从In ProgressAll Components at DC,返回“ M”列被编辑的事件对象。因此,旧值和新值不是“ G”列的值。而且,当触发器触发列“ G”的值时,该值就是更改后的值。通过这种方式,在这种情况下,当使用事件对象和触发器时,将检索更改后的“ G”列的值。

解决方法:

为了避免上述问题,该解决方法如何?在这种解决方法中,我建议在编辑之前保存列“ G”的值。为此,我使用一列。尽管有几种方法,但我认为这种解决方法很简单。此解决方法的流程如下。

  1. 首先,使用函数将列“ G”的当前值保存到列中。这是该流程的初始化。
    • 在此示例中,“ N”列用作在编辑之前保存值的列。
  2. 启动可安装触发器时,它将从“ N”列中检索过去的值,并将其与新值进行比较。当新值更改为All Components at DC时,它将在if中运行脚本并发送电子邮件。
  3. 将“ N”列的值更新为当前值。

当上述流程反映到您的脚本中时,请进行以下修改。同样,可以像下面的脚本一样修改使用事件对象的脚本。

修改后的脚本:

// Added
function saveCurrentValues() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tracker");
  var values = sheet.getRange(2, 7, sheet.getLastRow(), 1).getValues();
  sheet.getRange(2, 14, values.length, 1).setValues(values);
}

function sendNotification(e){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var cell = ss.getActiveCell().getA1Notation();
  var row = sheet.getActiveRange().getRow();
  var cellvalue = ss.getActiveCell().getDisplayValue().toString();
  var beforeEdit = sheet.getRange(1, 14, sheet.getLastRow(), 1).getValues(); // Added
  if(sheet.getName()=='Tracker' && sheet.getRange('G'+row).getValue()=='All Components at DC' && beforeEdit[row - 1][0] != 'All Components at DC') // Modified
  {
    var recipients = "xxx@xxx.com";
    var subject = "New Components Delivered to DC"
    var message = sheet.getRange('A'+ sheet.getActiveCell().getRowIndex()).getValue() + '\n TITLE: ' + sheet.getRange('F'+ sheet.getActiveCell().getRowIndex()).getValue() + '\n LANGUAGE: ' + sheet.getRange('E'+ sheet.getActiveCell().getRowIndex()).getValue()
    var body = sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + '\n ROW: ' + row + '\n TVD DATE: ' + message + '\n COMMENT: ' + cellvalue;
    var valColB=e.range.getSheet().getRange(e.range.getRow(),2).getValue();
    MailApp.sendEmail(recipients, subject, body);
  }
  saveCurrentValues(); // Added
}

注意:

  • saveCurrentValues()用于保存列“ G”的当前值。因此,复制并粘贴以上脚本之后,请首先运行saveCurrentValues()。这样,当前值将保存到“ N”列。
    • 列“ N”用作示例。因此,请修改您的环境。您还可以隐藏列。
  • 在这种解决方法中,当列“ G”的值从All Components at DC更改为其他值并且未更改时,if中的脚本不会运行。因此不会发送电子邮件。