根据单元格内容更改Google Sheet触发频率

时间:2018-03-30 13:04:33

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

在我的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中的分钟频率。然后,脚本应该以编程方式使用该信息创建触发器,例如:“如果Cell H2 =”Yes“,则使用B3和B4创建触发器,并且每隔x分钟/ x小时发送一封电子邮件,只要C列包含”是“。

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

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();
}

1 个答案:

答案 0 :(得分: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;
  }
}