GAS将变量传递给基于时间的触发器

时间:2012-07-20 14:17:35

标签: google-apps-script google-sheets

我有一个带有onEdit触发器的Google电子表格,可以创建第二个基于时间的触发器。

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

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

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

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

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

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

5 个答案:

答案 0 :(得分:3)

使用ScriptDB和新的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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分: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分钟(无论您要求的确切时间如何),因此有多个空间可以让多个函数调用相互干扰!!!