繁体   English   中英

如何使用 Google Apps 脚本延迟 google 表格中的时间触发?

[英]How to delay time trigger in google sheets using Google Apps Script?

我每 12 分钟就有来自外部软件的数据进入 Google 工作表。 但是,它不会清除旧数据,而是在工作表中附加新数据。 我想先清除旧数据。 为此,我创建了一个时间触发器,每 10 分钟运行一次并清除工作表。 现在这是棘手的部分:

  1. 工作表在 10 分钟后被清除
  2. 12 分钟后数据进来

有 2 分钟的间隔,其中工作表完全是空的,没有数据。 我想将这个差距缩小到 30 秒。 为此,我做了以下事情:

function ClearSheet(){
   
   var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Today_Import");
  Delay();
  sheet.getDataRange().clear();
  
   SpreadsheetApp.flush();
   TriggerDelete();
   SpreadsheetApp.flush();
   TriggerCreate()
}

function Delay(){

   SpreadsheetApp.flush();
   Utilities.sleep(85000);
}

function TriggerDelete() {
  var Triggers = ScriptApp.getProjectTriggers();

  for (var i = 0; i < Triggers.length; i++) {
    if (Triggers[i].getHandlerFunction() == "ClearSheet") {
      ScriptApp.deleteTrigger(Triggers[i])
    }
  }
}

function TriggerCreate(){
    ScriptApp.newTrigger("ClearSheet")
   .timeBased().everyMinutes(10).create();
}

我创建了一个延迟大约 1.2 分钟的ClearSheet() function。 清除该工作表后,将删除以前的触发器并安装新触发器,理想情况下,此新触发器应比前一个触发器运行大约 1.5 分钟,但它不会发生。

如何延迟我的触发器 function 以便它可以在 11-11.5 分钟而不是每 10 分钟后运行一次?

创建一个在特定时间运行的触发器怎么样? 在你的情况下比现在晚 11.5 分钟

  var date_now = new Date();
  date_now.setTime(_date.getTime() + (11*60000 + 30000) ); // = 11,5min

  ScriptApp.newTrigger(callfunction)
            .timeBased()
            .at(date_now)
            .create();

参考: https://developers.google.com/apps-script/reference/script/trigger-builder#timebased

您可以使用.after()来设置以毫秒为单位的精确时间,之后触发器运行,然后您可以再次创建它。

但是,Apps 脚本基于时间的触发器的问题在于它们天生就是不准确的。 即使您设置了一个确切的时间范围,它也可能会随着时间的推移而漂移,具体取决于脚本运行时或服务器引入的随机性。 即使是after()方法也可能在指定后运行一段时间,并且您可能会在其中一个周期内无意中清除整个工作表。

您可以考虑另一种方法,例如使用CacheService跟踪最后一行并尽可能频繁地检查新行。 然后当检测到新行时,您可以清除旧数据。 例如:

function TriggerCreate() {
  ScriptApp.newTrigger('ClearSheet').timeBased().after(1000).create()
}

function TriggerDelete() {
  var Triggers = ScriptApp.getProjectTriggers();

  for (var i = 0; i < Triggers.length; i++) {
    if (Triggers[i].getHandlerFunction() == "ClearSheet") {
      ScriptApp.deleteTrigger(Triggers[i])
    }
  }
}

function ClearSheet() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Today_Import")
  var current = sheet.getLastRow()
  var lastrow = CacheService.getDocumentCache().get("lastrow")
  if (current > lastrow) {
    if (lastrow > 0) {
      var range = sheet.getRange(1, 1, parseInt(lastrow))
      range.deleteCells(SpreadsheetApp.Dimension.ROWS)
    }
  }
  CacheService.getDocumentCache().put("lastrow", current, 600)
  
  TriggerDelete()
  TriggerCreate()
}

触发器旨在使用after()大致每秒运行一次,但实际上它的范围是 30 秒到 2 分钟。 根据您的需要,它可能仍然保持工作表几乎不断更新,并且它不会在任何时候完全空白,尽管较新的数据可能会在短时间内在底部找到。 请注意,如果您有用户手动向其中写入行,这可能会失败,但我想情况并非如此,因为您目前正在完全清除它。

您还可以将跟踪行的相同想法应用于 10 分钟触发器,而不是重新创建触发器。

至于您当前的脚本,可能是Utilities.sleep()不工作,因为它在 function 或类似的东西中,因为在我的示例中将它直接添加到ClearSheet()确实会延迟脚本。 请记住,这会使触发器保持运行,并且有一个触发器每日运行时间限制 您可能也不需要经常使用flush()

总而言之,如果您能以某种方式修改外部软件以在数据之前发送清晰的信号,那将是最好的,但除此之外,没有办法准确地每 11.5 分钟运行一次触发器。 您可以尝试将after()设置为 11.5 分钟,我认为它在更长的时间范围内更准确,但您最好的选择是考虑到时间可能会有所不同并使用不同的方法。

参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM