Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Google工作表上运行函数的脚本_Javascript_Google Apps Script_Google Sheets_Triggers - Fatal编程技术网

Javascript 在Google工作表上运行函数的脚本

Javascript 在Google工作表上运行函数的脚本,javascript,google-apps-script,google-sheets,triggers,Javascript,Google Apps Script,Google Sheets,Triggers,嗨, 我目前有一个runOnEdit脚本(如下所示),设置为在a列中的更改时触发,然后从D列中提取值,并通过一个函数运行它,然后在E列中返回值。它工作得很好。但是,由于我使用Zapier将更改推送到trigger列中,runOnEdit函数不起作用。根据研究,我知道onEdit无法检测API服务的更改。所以我想创建一个类似的函数,它每小时在Google工作表上运行一次,基本上检查一个时间戳列(B),并将其与另一个时间戳列(C)进行比较。如果它满足If条件,那么我希望它在每个单元格的返回列(E)中

嗨, 我目前有一个runOnEdit脚本(如下所示),设置为在a列中的更改时触发,然后从D列中提取值,并通过一个函数运行它,然后在E列中返回值。它工作得很好。但是,由于我使用Zapier将更改推送到trigger列中,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
}
下面是我的新脚本每小时运行一次的尝试。但我似乎不明白。 '''

函数runtimedisfunc(){
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sheet=ss.getSheetByName('DataFinal的副本');//源工作表
var testrange=sheet.getRange('A:Z');//要检查的范围
var o=testrange.range.offset(0,5)
var tsza=testrange.range.offset(0,2)
var tstdfunc=testrange.range.offset(0,3)
var v=e.范围偏移量(0,4)
var combaddvalue=v.getValue()
var timestampza=tsza.getValue()
var timestamptdfunc=tstdfunc.getValue()
if(timestampzatimestamptdfunc)){
var timedis=gettime(combaddvalue)
o、 设置值(timedis)
tstdfunc.setValue(新日期())
}
}
函数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(内容);
Logger.log(内容);
var time=json.rows[0]。元素[0]。duration.text;
var dis=json.rows[0].元素[0].距离.text;
var timedis=时间+“|”+dis
返回时间
}
''”

摘要
  • 您希望根据D列中的数据定期填充E列
  • 仅当D列中的数据不是“”时,才需要执行此操作
问题
  • 正如您所注意到的,
    onEdit
    不会触发API执行的编辑
  • 您希望每小时运行脚本,而不是OneEdit
解决方案
  • 使用可安装的定时驱动触发器,而不是
    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
}
函数bindATimedrivenTriggerToMe(){
var sh=SpreadsheetApp.getActive().getSheetByName(“DataFinal的副本”);
var lastRow=sh.getLastRow();
var v=sh.getRange(1,4,最后一行,1);
var values=v.getValues();
var o=sh.getRange(1,5,最后一行,1);
var-valueArray=[];
对于(变量i=0;i
您应该使用可安装触发器您的
函数runtimedisfunc()
是否绑定到可安装的时间驱动触发器?您好,是的,我已将runtimedisfunc()绑定到Google工作表上的“OnEdit”可安装触发器。如果我在trigger列中输入新数据,函数将正常运行并返回所需的结果。但是,当Zapier将更改推送到trigger列时,OnEdit触发器不会检测到更改并触发函数运行(我知道这是这里的问题)。谢谢!这正是我让它工作所需要的。为了我自己的学习目的,帮助我将来编写脚本,你能解释更多关于这些行的内容吗。var v=sh.getRange(1,4,最后一行,1);或者(var i=0;i0)要正确检索值。设置值也是如此-您需要创建一个二维值数组,该数组的维度与要设置它们的范围相同。我希望这能让它更清晰!相关帖子:和
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
}