2

我有一个带有onEdit()触发器的 Google 电子表格来创建基于第二次的触发器。

简单地说:当状态栏被编辑为“已批准”时,会创建一个触发器以在提供的项目完成日期发送反馈电子邮件。

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

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

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

var oneTimeOnly = ScriptApp.newTrigger("emailFeedback<strong>(regEmail)</strong>").timeBased().at(endDate).create();

.

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

4

5 回答 5

3

使用 ScriptDB 和 new Function(),我能够创建一种用于创建动态触发函数的方法。

解决方案的要点是将要触发的代码存储为带有要传递的参数的数据库:

"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

于 2013-08-26T15:00:05.547 回答
2

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

于 2013-03-14T20:07:18.843 回答
2

抱歉,没有办法做到这一点。

于 2012-07-20T15:47:08.217 回答
1

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

于 2013-03-13T17:21:20.813 回答
0

@user2166613 是对的,但有点短。这是如何做到的。

我展示了一个使用 after() 触发器的示例。这是一个非常有趣的用例,因为它允许将耗时的任务与 Web 应用程序调用分离,因此调用会立即返回控制并在后台完成处理。

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

// 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 分钟(无论您要求什么确切时间),因此有足够的空间让多个函数调用相互干扰!!!

于 2016-02-26T14:47:00.493 回答