2011-10-21 87 views
38

我有一个Apps脚本不断发生此错误。通过通知邮件判断,看起来时间限制是5分钟。有谁知道是否有办法延长这个时间限制?或者,有没有办法再次调用Apps脚本,并从停止的地方继续?任何帮助表示赞赏。在Google Apps脚本中超出了最长执行时间

+2

你能分享你正在运行的脚本?您可以调整它以使其更快。 – Eduardo

+2

您可以通过使用HTML服务在您的工作的子集上启动脚本的单独“迭代”来弯曲规则。 [Bruce McPherson已经发表了博客。](http://ramblings.mcpher.com/Home/excelquirks/htmlservice/parallel) – Mogsdad

+1

如果您是商业客户,现在可以注册[Early Access to App Maker] (https://developers.google.com/apps-script/guides/apps-script-eap),其中包含[Flexible Quotas](https://developers.google.com/apps-script/guides/services/quotas) #flexible_quotas_early_access)。 – browly

回答

56

有一两件事你可以做(​​这当然取决于你试图完成什么)是:

  1. 存储必要的信息(即像一个循环计数器)在电子表格或其他永久存储(即ScriptProperties)。
  2. 让你的脚本每五分钟左右终止一次。
  3. 设置一个时间驱动的触发器,每5分钟运行脚本(或使用Script service以编程方式创建触发器)。
  4. 在每次运行中,从您使用的永久存储中读取已保存的数据,并继续从停止的位置运行脚本。

这不是一个适合所有人的解决方案,如果你发布你的代码,人们将能够更好地帮助你。

下面是一个脚本,我每天都在使用的简化代码摘录:

function runMe() { 
    var startTime= (new Date()).getTime(); 

    //do some work here 

    var scriptProperties = PropertiesService.getScriptProperties(); 
    var startRow= scriptProperties.getProperty('start_row'); 
    for(var ii = startRow; ii <= size; ii++) { 
    var currTime = (new Date()).getTime(); 
    if(currTime - startTime >= MAX_RUNNING_TIME) { 
     scriptProperties.setProperty("start_row", ii); 
     ScriptApp.newTrigger("runMe") 
       .timeBased() 
       .at(new Date(currTime+REASONABLE_TIME_TO_WAIT)) 
       .create(); 
     break; 
    } else { 
     doSomeWork(); 
    } 
    } 

    //do some more work here 

} 

注1:变量REASONABLE_TIME_TO_WAIT应应足够大,新的触发火灾。 (我把它设置为5分钟,但我认为它可能比这少)。

注#2:doSomeWork()必须是一个执行相对较快(我会说不到1分钟)的函数。

注意#3:谷歌已弃用Script Properties,并介绍Properties Service代替。该功能已相应修改。

+1

触发器的使用频率是否有限制?我认为每24小时可能会有触发限制或什么...谢谢! – Kalin

+0

我不认为这将适用于附加组件。附加的定时触发器只允许每小时执行一次。你知道任何其他解决方案来保持任务运行并处理来自excel工作表的大量数据。 – angelokh

+0

这有一个副作用,即在项目的触发列表中保留所有基于旧时间的触发器......不确定过期的时间触发器应该被清除。 – staggart

21

此外,请尽量减少对Google服务的呼叫量。例如,如果您想要更改电子表格中的一系列单元格,请不要读取每个单元格,将其更改并存回。 改为将整个范围(使用Range.getValues())读入内存,对其进行变异并将其全部保存(使用Range.setValues())。

这应该为您节省很多执行时间。

5

我已经使用ScriptDB来保存我的地方,同时在循环中处理大量的信息。该脚本可以/超过5分钟的限制。通过在每次运行期间更新ScriptDb,脚本可以从数据库中读取状态,并选取停止的位置,直到完成所有处理。试试这个策略,我想你会对结果感到满意。

+1

对在电子表格中反复显示750个电子邮件地址的脚本有类似的问题。你如何存储剧本停止的地方并恢复执行? – jwesonga

+0

可以提供更多详细信息...如果可能,请提供示例代码..或链接到更多详细信息。 –

+0

ScriptDb已弃用。 –

12

Anton Soradoi's answer看起来不错,但是考虑使用Cache Service而不是将数据存储到临时表单中。

function getRssFeed() { 
    var cache = CacheService.getPublicCache(); 
    var cached = cache.get("rss-feed-contents"); 
    if (cached != null) { 
    return cached; 
    } 
    var result = UrlFetchApp.fetch("http://example.com/my-slow-rss-feed.xml"); // takes 20 seconds 
    var contents = result.getContentText(); 
    cache.put("rss-feed-contents", contents, 1500); // cache for 25 minutes 
    return contents; 
} 

同时请注意,2014年4月的limitation of script runtime为6分钟

+0

这对我来说似乎是解决问题的最简单方法,因为您不需要设置任何其他资源(电子表格,数据库等),也不需要关心任何其他资源(所有脚本逻辑都保留在脚本本身内)。谢谢! – dubrox

+1

你能举一个广义函数的例子吗? –

4

如果您使用的是G Suite Business或Enterprise版本。 您可以register early access for App Maker应用程序制造商启用后,您的脚本运行运行时会增加运行时间6分钟到30分钟左右的应用程序制造商 :)

更多细节Click here

相关问题