【问题标题】:Google App Script to trigger on cell value change用于触发单元格值更改的 Google App 脚本
【发布时间】:2020-12-17 02:39:44
【问题描述】:

我是一个新手,一直在使用一个简单的应用脚本来发送带有触发器 onEdit 和 onChange 的电子邮件。但是,我的工作表有十多张,并且任何一张表中的任何编辑/更改(由我或通过计算完成)都会发送一封电子邮件,从而导致意外的垃圾邮件!为避免这种情况,如果我可以使用一些代码仅根据对特定单元格值的任何更改在特定工作表中发送电子邮件,我的问题将得到解决。我的外发电子邮件信息很短,整个信息都在一个单元格 (C2) 中。如果我可以添加一行代码来监视该单元格 C2 中的任何更改,并在有更改时发送一封电子邮件,就是这样!我就完了。我的脚本如下:

function sendEmail(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1=ss.getSheetByName('Email');
var emailAddress = sheet1.getRange(2,1).getValue();
var subject = sheet1.getRange(2,2).getValue();
var message = sheet1.getRange(2,3).getValue();
MailApp.sendEmail(emailAddress, subject, message);
}

【问题讨论】:

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


【解决方案1】:

答案:

您可以使用onEdit() 和条件来做到这一点。

代码示例:

function onEdit(e) {
  const specificSheet = "Email"   // for example
  const specificCell = "C2"       // for example

  let sheetCheck = (e.range.getSheet().getName() == specificSheet)
  let cellCheck = (e.range.getA1Notation() == specificCell)

  if (!(sheetCheck && cellCheck)) {
    return
  }
  else {
    sendEmail()
  }
}

这个函数的概要:

  • 定义要检查的特定单元格的工作表和 A1 表示法
  • 获取刚刚编辑的单元格的工作表和 A1 符号
  • 如果工作表或单元格不是定义的特定单元格,则返回(使用De Morgan's law)
  • 如果单元格和工作表正确,则运行 sendEmail()

参考资料:

【讨论】:

  • 嗨拉法,非常感谢您的解决方案!我已将它添加到我的两个脚本中,就在我的脚本之前,现在正在测试它们。我会及时向大家发布。但是,请注意,在这两种情况下,“编辑”都是计算出来的,而不是用户输入的,所以我的两个原始脚本触发器都是 onChange(因为 onEdit 不起作用)并且你的脚本以 onEdit 开头。我需要将触发器更改为 onEdit,还是应该将脚本更改为 onChange?再次感谢!
【解决方案2】:

根据答案,这就是我的结果,因为我有几个范围要检查:

function onEdit(e){
  if(wasEdited(e, range1)){  // e.g. range1 = "Sheet1!A5"
    // handle range1 change
  }
  if(wasEdited(e, range2)){  // e.g. range2 = "Sheet1!A7"
    // handle range2 change
  }
}
function wasEdited(e, range){
  let tab = getTabFromA1Range(range)
  let cell = getRangeFromA1Range(range)
  return e.range.getSheet().getName() == tab && e.range.getA1Notation() == cell
}
function getTabFromA1Range(a1Range){
  return a1Range.substring(0, a1Range.indexOf("!"))
}
function getRangeFromA1Range(a1Range){
  return a1Range.substring(a1Range.indexOf("!")+1)
}

【讨论】:

    【解决方案3】:

    经过进一步研究,以下解决方案似乎效果最好:

    function sendEmail(){
    Utilities.sleep(30000);
    var ss=SpreadsheetApp.getActiveSpreadsheet();
    var data=ss.getActiveSheet().getActiveCell().getA1Notation();
    var sheetname = ss.getActiveSheet().getName();
    var sheet1=ss.getSheetByName('Email');
    var emailAddress = sheet1.getRange(2,1).getValue();
    var subject = sheet1.getRange(2,2).getValue();
    var message = sheet1.getRange(2,3).getValue();
    if(data.indexOf('A:C')!=-1.23456789) {
    MailApp.sendEmail(emailAddress, subject, message);
    }
    
    };
    

    关键似乎是第10行的“if语句”。请注意我在脚本中添加的半分钟时间延迟。这是因为没有它,在触发器激活时,之前的电子邮件会发出,而不是当前的。显然,我的应用在同步方面有轻微延迟,并且在所有当前数据填充到相关单元格之前触发了触发器!

    【讨论】:

    • 请正确格式化您的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多