[英]How to delay time trigger in google sheets using Google Apps Script?
我每 12 分钟就有来自外部软件的数据进入 Google 工作表。 但是,它不会清除旧数据,而是在工作表中附加新数据。 我想先清除旧数据。 为此,我创建了一个时间触发器,每 10 分钟运行一次并清除工作表。 现在这是棘手的部分:
有 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.