2012-07-20 50 views
2

我有一个带有onEdit触发器的Google电子表格,用于创建第二个基于时间的触发器。GAS将变量传递给基于时间的触发器

简单地说:当status列被编辑为'Approved'时,会创建一个触发器,以在提供的项目完成日期发送反馈电子邮件。

var oneTimeOnly = ScriptApp.newTrigger("emailFeedback").timeBased().at(endDate).create(); 

我希望将变量传递给第二个触发器。我可以创建项目属性或在电子表格中添加一列。但是,创建触发器时传递该变量会更简单。

当我在newTrigger引号中插入任何其他字符时,这会导致函数的全部内容存储在触发器中(随后失败)。

var oneTimeOnly = ScriptApp.newTrigger(“emailFeedback (regEmail)”).timeBased()。at(endDate).create();

有没有办法在触发器内存储变量?

+0

GAS通过 j08691 2013-03-13 17:23:51

回答

3

使用ScriptDB和新的函数(),我能够创建一个创建动态触发函数的方法。

解决方案的要点是存储要触发的代码是要传递与参数DB:

"myFunction('Hello world')" 

然后,脚本启动的时候,作为一个全局变量,你附加从您的ScriptDB新创建的功能。 (我在动态我的链接下面的做到了这一点。)

globalFunctions.callThisOne = new Function("e", "myFunction("Hello world")); 

最后,当您创建触发器,您可以使用全局可访问的功能,例如创建它:

ScriptApp.newTrigger("globalFunctions.callThisOne").timeBased().everyDay(1).create(); 

我已经写了一篇关于此事的短文,并张贴了消息来源。希望它是有用的。

你可以阅读更多关于它在这里:http://goo.gl/wbUqH6

或者看到这里的代码:http://goo.gl/zjUiYe

+0

这是行得通的,但看起来GAS团队已经删除了以我描述的方式调用函数的能力。 – fooby 2013-08-28 10:46:23

+0

我还没有测试过,但理论看起来很合理。如果它有效,它会很棒! :) – John 2014-02-21 17:10:20

2

对不起,没有办法做到这一点。

1

使用ScriptProperties.setProperty()来存储可以通过触发方法访问的序列化参数。

+0

您可以在需要设置此属性的位置提供一些上下文吗? – Qpirate 2013-03-13 17:41:14

2

据我所知,正确的是,问题是如何将数据传递给谷歌脚本项目中的时间触发函数。 Eoin描述了一种情况,但你可能面对很多情况。 您的脚本处理可能会运行很长时间的复杂电子表格的经典情况。正如你可能知道每个脚本有大约6分钟的运行时间限制。这种情况下,应该将脚本分成较小的逻辑分区,并在每个逻辑分区的末尾创建一个新的触发器以供下一部分使用。好的,但下一部分必须知道当前正在运行的脚本变量的一些数据。因为没有办法通过newTrigger()传递这些数据,所以你可以创建一个快照并以序列化的方式放入脚本属性上下文中。 一个简单的方法来做ScriptProperties.setProperty()

0

@ user2166613是正确的,但有点短。这是如何做到这一点。

我显示了一个使用after()触发器的示例。这是一个非常有趣的用例,因为它允许将耗时的任务从例如网页应用程序调用,所以调用立即返回控制,并在后台完成处理。

在我的示例中,我调整了延迟运行的函数中的工作表的列宽。

// call this function to set a time based trigger and transfer parameters 
function setTimeTrigger_AdaptColumnWidths() { 
    var ssId = SpreadsheetApp.getActiveSpreadsheet().getId(); 
    var wsId = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId(); 

    var scriptProperties = PropertiesService.getScriptProperties(); 
    scriptProperties.setProperty('spreadsheetId', ssId); 
    scriptProperties.setProperty('worksheetId', wsId); 

    // Delay 10 secs, but real execution time may vary up to 15 min! 
    ScriptApp.newTrigger('adaptColumnWidths').timeBased().after(10000).create(); 
} 

// this function is called by the trigger 
function adaptColumnWidths() { 
    var scriptProperties = PropertiesService.getScriptProperties(); 
    ssId = scriptProperties.getProperty('spreadsheetId'); 
    wsId = scriptProperties.getProperty('worksheetId'); 

    // getSheetById() is a custom function – see below – not yet in Spreadsheet Class! 
    sheet = getSheetById(SpreadsheetApp.openById(ssId), wsId); 

    // now do what we want to do in the timeBased trigger 
    for (var i = 1; i <= sheet.getLastColumn(); i++){ 
    sheet.autoResizeColumn(i); 
    } 
} 

// ----- 

// custom function – hopefully this will become a method of Spreadsheet Class any time soon 
function getSheetById(ss, wsId) { 
    var sheets = ss.getSheets(); 
    for (var i=0; i<sheets.length; i++) { 
    if (sheets[i].getSheetId() == wsId) return sheets[i]; 
    } 
} 

请注意,您在数据空间存储这里是共同所有的函数调用。因此在短时间内多次呼叫可以覆盖其他参数。

在我的用例中,这不是问题,因为电子表格和工作表不会改变。但不要尝试传输可能因呼叫而改变的数据。

执行的真正时刻可能会长达15分钟(无论您要求什么确切时间),因此有足够的空间让多个函数调用互相干扰!