简体   繁体   中英

Script on Google Sheet to Run Function

Sample Data Sheet

Hi, I currently have a runOnEdit script (below) that is set to trigger on changes in Column A, then pull the value from Column D and run it through a function and return the value in Column E. It works great. However, because I am using Zapier to push changes into the trigger column, the runOnEdit function is not working. Based on research, I know that onEdit wont detect changes from API services. So I would like to create a similar function that runs hourly on Google Sheets that basically checks a timestamp column (B) and compares it to another timestamp column (C). If it meets the if condition, then I want it to return the function value in the return column (E) for each cell. I'm using the timestamps to determine whether the trigger column was updated recently in which case I want the sub function to run and if it has not been run recently, then I want it to stop and leave the current value that exists in the result column E.

This is my current runOnEdit script that works great.

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
}

Here is the attempt at my new script to run hourly. But i can't seem to figure it out. '''

    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

}

'''

Summary

  • You want to regularly populate column E based on data from column D
  • You want to do so only if the data in column D is not ""

Issue

  • As you noticed onEdit does not trigger for edits performed by an API
  • You want to run your script hourly rather than onEdit

Solution

  • Use an installable timed-driven trigger instead of the onEdit trigger

在此处输入图像描述

  • This will allow to run your script hourly without any implementation of timestamps or similarfeatures in you code
  • Just keep in mind that time-driven triggers don't support event objects like eg e.range - since there might not be any range edited at the moment when the trigger fires
  • You need to rewrite your function in such a way that it is not reliant on event objects

Sample:

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM