如何延迟时间触发在谷歌表使用谷歌应用程序脚本?



我有数据从外部软件每12分钟后谷歌表。但是,它不会清除旧数据,而是在工作表中添加新数据。我想先清除旧数据。为此,我创建了一个时间触发器,每隔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()函数。在该工作表被清除后,将删除先前的触发器并安装新触发器,理想情况下,新触发器应该比先前的触发器晚大约1.5分钟运行,但它没有发生。

如何延迟我的触发功能,使它可以运行后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时基

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

然而,Apps Script基于时间的触发器的问题在于它们本质上是不准确的。即使您设置了一个精确的时间范围,它也可能随着时间的推移而漂移,这取决于脚本运行时或服务器引入的随机性。甚至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()不工作,因为它在函数或类似的东西内,因为在我的示例中将其直接添加到ClearSheet()中确实会延迟脚本。请记住,这将保持触发器运行,并且有一个触发器每日运行时间限制。您可能也不需要经常使用flush()

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

引用:

  • 时间偏差问题跟踪
  • CacheService
  • Apps脚本配额
  • 基于时间的触发方法

相关内容

最新更新