首页 文章

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

提问于
浏览
0

在我的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列包含”是“ .

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

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 回答

  • 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;
      }
    }
    

相关问题