【问题标题】:Script on Google Sheet to Run FunctionGoogle Sheet 上的脚本以运行函数
【发布时间】:2020-06-01 03:35:54
【问题描述】:

Sample Data Sheet

嗨, 我目前有一个 runOnEdit 脚本(如下),它设置为触发 A 列中的更改,然后从 D 列中提取值并通过函数运行它并返回 E 列中的值。效果很好。但是,因为我使用 Zapier 将更改推送到触发器列,所以 runOnEdit 函数不起作用。根据研究,我知道 onEdit 不会检测到 API 服务的更改。所以我想创建一个类似的函数,在 Google 表格上每小时运行一次,它基本上检查时间戳列 (B) 并将其与另一个时间戳列 (C) 进行比较。如果它满足 if 条件,那么我希望它在每个单元格的返回列 (E) 中返回函数值。我正在使用时间戳来确定最近是否更新了触发列,在这种情况下,我希望子函数运行,如果它最近没有运行,那么我希望它停止并保留结果中存在的当前值E栏。

这是我当前运行良好的 runOnEdit 脚本。

function runonEdit(e) {
  var sh = e.source.getActiveSheet();
  if(sh.getName() !== "Copy of DataFinal" || e.range.columnStart !== 1) return;// 1 is A, 2 is B, 3 is C and so on
  var v = e.range.offset(0,5)
  var value =v.getValue()
  var o = e.range.offset(0, 4)
  if (value == "") {
    o.setValue("")
   return null;
} 
  var timedis = gettime(value)
      o.setValue(timedis)
}
function gettime(f) {
  var res= UrlFetchApp.fetch("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+f+"&key=MYKEY");
    var content = res.getContentText();
    var json = JSON.parse(content);
      Logger.log(content);
   var time=json.rows[0].elements[0].duration.text;
  var dis=json.rows[0].elements[0].distance.text;
  var timedis=time+"|"+dis

return timedis
}

这是我的新脚本每小时运行一次的尝试。但我似乎无法弄清楚。 '''

    function runtimedisfunc() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Copy of DataFinal'); //source sheet
  var testrange = sheet.getRange('A:Z'); //range to check
  var o = testrange.range.offset(0, 5)
  var tsza = testrange.range.offset(0,2)
  var tstdfunc = testrange.range.offset(0,3)
  var v = e.range.offset(0,4)
  var combaddvalue =v.getValue()
  var timestampza= tsza.getValue()
  var timestamptdfunc= tstdfunc.getValue()
  if (timestampza < timestamptdfunc){
    return null;
  }
  if (combaddvalue == "") {
    o.setValue("")
   return null;
} 
  if ((timestampza != "") || (timestampza > timestamptdfunc)){

   var timedis = gettime(combaddvalue)
      o.setValue(timedis)
      tstdfunc.setValue(new Date())
}
}
function gettime(f) {
  var res= UrlFetchApp.fetch("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+f+"&key=MYKEY");
    var content = res.getContentText();
    var json = JSON.parse(content);
      Logger.log(content);
   var time=json.rows[0].elements[0].duration.text;
  var dis=json.rows[0].elements[0].distance.text;
  var timedis=time+"|"+dis

return timedis

}

'''

【问题讨论】:

  • 您的function runtimedisfunc() 是否绑定到可安装的时间驱动触发器?
  • 嗨,是的,我已将 runtimedisfunc() 绑定到 Google 表格上的“OnEdit”可安装触发器。如果我在触发器列中输入新数据,该函数将完美运行并返回我想要的结果。但是,当 Zapier 将更改推送到触发器列时,OnEdit 触发器不会检测到更改并触发函数运行(我知道这是这里的问题)。

标签: javascript google-apps-script google-sheets triggers


【解决方案1】:

总结

  • 您希望根据 D 列中的数据定期填充 E 列
  • 只有当 D 列中的数据不是“”时,您才希望这样做

问题

  • 如您所见,onEdit 不会触发 API 执行的编辑
  • 您希望每小时运行一次脚本而不是 onEdit

解决方案

  • 使用可安装的定时驱动触发器代替onEdit 触发器

  • 这将允许您每小时运行一次脚本,而无需在代码中实现任何时间戳或类似功能
  • 请记住,时间驱动的触发器不支持事件对象,例如e.range - 因为在触发触发时可能没有编辑任何范围
  • 您需要重写您的函数,使其不依赖于事件对象

示例:

function bindATimedrivenTriggerToMe() {
  var sh = SpreadsheetApp.getActive().getSheetByName("Copy of DataFinal");
  var lastRow = sh.getLastRow();
  var v = sh.getRange(1,4,lastRow,1);
  var values =v.getValues();
  var o = sh.getRange(1,5,lastRow,1);
  var valueArray = [];
  for (var i =0; i < values.length; i++){
    var value = values[i][0];
    valueArray[i] = [];
    if (value == "") {
      valueArray[i].push("");
    } else {
      var timedis = gettime(value);
      valueArray[i].push(timedis);
    }
  }
 o.setValues(valueArray);
}

function gettime(f) {
  var res= UrlFetchApp.fetch("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+f+"&key=MYKEY");
    var content = res.getContentText();
    var json = JSON.parse(content);
      Logger.log(content);
   var time=json.rows[0].elements[0].duration.text;
  var dis=json.rows[0].elements[0].distance.text;
  var timedis=time+"|"+dis

return timedis
}

【讨论】:

  • 谢谢!这正是我让它工作所需要的。为了我自己的学习目的,以帮助我未来的脚本,你能解释更多关于这些行的信息吗? var v = sh.getRange(1,4,lastRow,1);或 (var i =0; i
  • 您必须知道,Google Shhets 中的值始终存储为值域,即二维值数组。因此,即使您只检索一列(您可能认为是一维对象),实际上它也是一个嵌套数组,如果您必须同时指示行索引(在本例中为 i)和列索引(对于 1 列范围始终为0) 以正确检索值。设置值也是如此 - 您需要创建一个二维值数组,其尺寸与您想要设置它们的范围相同。我希望这能让它更清楚!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多