【问题标题】:Change Google Sheet trigger frequency based on cell contents根据单元格内容更改 Google Sheet 触发频率
【发布时间】:2018-03-30 13:04:33
【问题描述】:

在我的 Google 表格“监视列表”中,我有以下代码:

    var EMAIL_SENT = "EMAIL_SENT";

function sendEmailsAdvanced() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Watchlist");  // To only handle the Watchlist sheet  
  var d = new Date();
  var timeStamp = d.getTime();
  var currentTime = d.toLocaleTimeString();
  var startRow = 8;  // First row of data to process
  var numRows = sheet.getLastRow()
  var dataRange = sheet.getRange(startRow, 1, numRows, 19)  // Fetch the range of cells
  // Fetch values for each row in the Range.
  var data = dataRange.getValues() ;
  for (var i = 0; i < data.length; ++i) {
    var row = data[i];
    if (row[2] === "yes" && row[18] === "" ) {    // Trigger only if Column C is "Yes"
      var emailAddress = row[0];  // First column
      var message = row[1];       // Second column
      var emailSent = row[19];
     if (emailSent != EMAIL_SENT) {
      var subject = "Buy Trigger for " + row[3] + " has been reached! Last updated: " + currentTime; // Add "Yes" although by your trigger logic it will always say yes in the email
      MailApp.sendEmail(emailAddress, subject, message);
      sheet.getRange(startRow + i, 19).setValue(EMAIL_SENT);
      SpreadsheetApp.flush();
     }
    }   
  }
}

只要 C 列中的相应行包含“是”,然后将文本“EMAIL_SENT”写入 S 列,就会发送一封电子邮件。一旦 S 列包含“EMAIL_SENT”,就不会再发送邮件。设置为“每分钟”的时间驱动触发器调用此函数。

现在我想补充一点,我可以在 Google 表格本身中定义触发频率。因此,我希望能够定义单元格 B3 中的每小时频率和单元格 B4 中的分钟频率。然后,脚本应该使用该信息以编程方式创建触发器,例如:“如果单元格 H2 =“是”,则使用 B3 和 B4 创建触发器,并每 x 分钟/x 小时发送一封电子邮件,只要 C 列包含“是”。

我发现这个 sn-p 以编程方式创建一个触发器,但我不知道如何将它引用到单元格内容并覆盖设置为“每分钟”的现有触发器:

ScriptApp.newTrigger('myFunction'):   create new trigger
         .timeBase()              :   build time-based trigger
         .everyHours(6)           :   every 6 hours
         .create()                :   creates the trigger

可在此处找到相应的 Google 表格:Watchlist Sheet

所以我现在编写了这个 onEdit() 函数,以便通过简单的 onEdit 触发器创建可安装的触发器,但是每当我更改单元格 B4 时,这不会创建新触发器,因为 onEdit 触发器似乎没有被调用。有什么想法吗?

function onEdit() {

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Watchlist");  // To only handle the Watchlist sheet 

// Deletes all triggers in the current project.
 var triggers = ScriptApp.getProjectTriggers();
 for (var i = 0; i < triggers.length; i++) {
   ScriptApp.deleteTrigger(triggers[i]);
 }

// Create new trigger based on B4 minute information
ScriptApp.newTrigger('sendEmailsAdvanced')
    .timeBased()
    .everyMinutes(sheet.getRange("B4").getValue())
    .create();
}

【问题讨论】:

  • 使用您的值,而不是硬编码的6。您可以使用工作表中的其他值来确定是调用 everyHours 还是其他时间单位,例如if (b3value &gt; 0) { ...
  • 谢谢,但是我不能只输入 .everyHours(b3),如何引用 B3 的值?
  • 您发布的代码显示了如何从给定的工作表中获取值:someSheet.getRange("someRange").getValue()。请查看有关任何不熟悉的方法的 Apps 脚本文档。有些允许多种输入样式(技术上称为“具有多个方法签名”),例如Sheet.getRange 接受“A1”样式字符串、2-4 个数值等。这些应该出现在编辑器的自动完成功能中。
  • 当您触发触发器时,它是根据当时的值生成的。它不是一个永久的链接,变化会在其中得到反映。如果您更改 b3 中的值,您将需要 1) 删除之前创建的触发器,以及 2) 创建一个新触发器。
  • 您可以使用简单的onEdit(e) 函数(在应用程序脚本文档中查找“简单触发器”)在所需配置表上的事件范围为 b3 或 b4 时调用时间驱动创建函数。

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


【解决方案1】:

简单触发器不能做任何需要权限的事情,包括修改触发器。您将需要使用可安装的 onedit:

function myFunction() {
  ScriptApp.newTrigger('bar')
  .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()).onEdit().create();

}




function bar(e){
  var triggers = ScriptApp.getProjectTriggers();
 for (var i = 0; i < triggers.length; i++) {
   if(triggers[i].getEventType() != ScriptApp.EventType.ON_EDIT){
   ScriptApp.deleteTrigger(triggers[i]);
   }
 }

  ScriptApp.newTrigger('baz')
    .timeBased()
    .everyMinutes(
     SpreadsheetApp.getActiveSheet().getRange("a1").getValue())
    .create();
}

function baz(){}

myFunction 的工作可以在触发器编辑器中完成,因为它是一次性使用的

这仅在 A1 的分钟触发器具有有效分钟数时才有效:5,10,15,30 第一个函数中的小时数将是 1,2,4,6,8,12

如果号码无效,旧触发器将被删除,但不会创建新触发器,并且您不会知道它,直到您收到我认为默认为每天午夜一次的错误电子邮件。

您可能需要创建一个函数来计算范围内的值,而不是直接使用范围值:

...

    ScriptApp.newTrigger('baz')
      .timeBased().everyMinutes(
       time(SpreadsheetApp.getActiveSheet().getRange("a1").getValue()))
      .create();

...

function time(t){
  switch(t){
    case "A":
      return 5;
    case "B":
      return 10;
    case "C":
      return 15;
    default:
      return 30;
  }
}

【讨论】:

  • 谢谢贾里德。这完美无缺。当我与其他人共享此工作表并且他们制作自己的本地副本时,我现在唯一的问题是为了使其工作,他们需要运行“sendEmailsAdvanced”功能才能单击该安全警告并允许权限然后运行myFunction 一次,但这应该是可管理的。再次感谢,复活节快乐
猜你喜欢
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多