如何在电子表格完成计算之前暂停应用程序脚本

时间:2012-10-03 14:51:04

标签: google-apps-script google-sheets

由于谷歌电子表格不支持迭代,我编写了自己的简单应用程序脚本,根据电子表格输出的计算调整输入。但是,在我更改输入变量后,电子表格会重新计算,但应用程序脚本似乎不会等待重新计算,因此我最终会检索诸如“Thinking ...”或“#NA”之类的值。有没有办法暂停脚本并等待计算完成,然后再转到脚本中的下一行?

目前,我只是使用循环来观察单元格,但我想知道是否有一种更优雅的方式来暂停执行,直到完成工作表的计算。

我编写了很多Excel宏,Excel VBA始终等待计算完成,然后再转到代码中的下一行。 Apps脚本似乎没有这样做,所以我希望有一个简单的方法来做到这一点。

第二个问题:因为这个迭代可能需要一些时间,如何中断并终止脚本运行?我似乎找不到办法做到这一点。

5 个答案:

答案 0 :(得分:5)

脚本在大约6分钟后超时,以防止无限循环和不断运行的程序。我不认为有一种手动方式来停止脚本。

编辑:哎呀,忘了回答你的第一个问题:我认为onEdit在重新计算值后运行,但显然我没有使用足够的公式来看到这一点。如果它没有等待,那么最好的方法是做这样的事情:

while(value === "Thinking..." || value === "#NA") {
  Utilities.sleep(10000);
}

暂停脚本几秒钟,然后再次检查。

答案 1 :(得分:3)

这是一种阻止下一个脚本启动的简单方法,直到当前脚本在Google Apps脚本中完成。只需在连续处理的每个脚本之后添加对testWait()的调用。 SpreadsheetApp.flush()似乎也将电子表格上的超时计时器重置为默认的5分钟,这样您就有更多时间一次处理多个脚本。

//holds processing of next script till last one has completed
function testWait(){
  var lock = LockService.getScriptLock(); lock.waitLock(300000); 
  SpreadsheetApp.flush(); lock.releaseLock();
}

答案 2 :(得分:2)

我还在Excel VBA中写了一些内容,其中本机计算功能派上用场。我曾多次在Google Apps / Docs中遇到同样的问题,希望在计算完成后执行代码。我想知道为什么Google Apps / Docs中没有原生功能来处理这个问题。无论如何,我写了这段代码来解决问题。希望能帮助到你。

function onEdit() {

Refresh();

};

function Refresh () {

     var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
     var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");

     // set the range wherever you want to make sure loading is done    

     var range = sheet.getRange('A:A')
     var values = range.getValues();

     var string = values.toString();

     var loading = "Loading";

                    do
                      {var randomWait = Math.floor(Math.random()*1+0); randomWait;}
                    while (string.search(loading) ==! 0);

      range.copyTo(sheet2.getRange('A1'), {contentsOnly:true});

customMsgBox();

};

function customMsgBox() {
  Browser.msgBox("Data refreshed.");
};

以下是行动中的一个例子:
https://docs.google.com/spreadsheet/ccc?key=0AkK50_KKCI_pdHJvQXdnTmpiOWM4Rk5PV2k5OUNudVE#gid=0

如果你想玩它,请复制一份。

答案 3 :(得分:1)

我有同样的问题。我通过使用2个脚本来解决此问题,以确保电子表格具有所需的数据。

第一个脚本提供了一个种子值,以通过IMPORTXML函数填充电子表格。

第二个脚本处理此数据。

我使用基于时间的触发器来运行脚本,从而为第一个脚本完成留出足够的时间

答案 4 :(得分:0)

您可以将递归结构放在code.js文件中,而不是放在电子表格中。 Javascript可以很好地处理递归。然后,您可以让脚本在每次迭代时(或每次100次)更新电子表格。