Javascript Google Sheets脚本中的距离未定义错误

Javascript Google Sheets脚本中的距离未定义错误,javascript,google-maps,google-maps-api-3,google-apps-script,google-sheets,Javascript,Google Maps,Google Maps Api 3,Google Apps Script,Google Sheets,好的,所以我试着制作一个程序,通过一个分包商列表和他们的数据,然后制作一个新的表格,填充附近的分包商 我遇到的问题是,当为分包商指定的位置与作业位置相同时,将返回一个错误。具体地说:“TypeError:无法将未定义的属性0.0设置为。”在脚本编辑器的执行记录中,我在代码失败之前得到了此错误 [14-07-11 12:20:29:418 EDT] Maps.newDirectionFinder() [0 seconds] [14-07-11 12:20:29:418 EDT] Direction

好的,所以我试着制作一个程序,通过一个分包商列表和他们的数据,然后制作一个新的表格,填充附近的分包商

我遇到的问题是,当为分包商指定的位置与作业位置相同时,将返回一个错误。具体地说:“TypeError:无法将未定义的属性0.0设置为。”在脚本编辑器的执行记录中,我在代码失败之前得到了此错误

[14-07-11 12:20:29:418 EDT] Maps.newDirectionFinder() [0 seconds]
[14-07-11 12:20:29:418 EDT] DirectionFinder.setOrigin([Louisville, KY]) [0 seconds]
[14-07-11 12:20:29:419 EDT] DirectionFinder.setDestination([3515 Newburg rd, Louisville, KY]) [0 seconds]
[14-07-11 12:20:29:476 EDT] DirectionFinder.getDirections() [0.057 seconds]
[14-07-11 12:20:30:043 EDT] Execution failed: TypeError: Cannot set property "0.0" of undefined to "". (line 99, file "Code") [6.364 seconds total runtime]
在这种情况下,我有没有办法处理这个错误并允许它通过?我尝试创建一个dist变量,如果距离返回未定义,则将其设置为0,但我仍然收到此错误

我的程序的完整代码如下

/**
 * A shared helper function used to obtain the full set of directions
 * information between two addresses. Uses the Apps Script Maps Service.
 *
 * @param {String} origin The starting address.
 * @param {String} destination The ending address.
 * @return {Object} The directions response object.
 */
function getDirections_(origin, destination) {
  var directionFinder = Maps.newDirectionFinder();
  directionFinder.setOrigin(origin);
  directionFinder.setDestination(destination);
  var directions = directionFinder.getDirections();
  if (typeof directions.routes[0] != 'undefined'){
  var dist = directions.routes[0].legs[0].distance.value
  }
  if (dist == 0 && origin == ', ') {
    dist = 100000;
  }
  return directions;
}

/**
 * A special function that runs when the spreadsheet is open, used to add a
 * custom menu to the spreadsheet.
 */
function onOpen() {
  var spreadsheet = SpreadsheetApp.getActive();
  var menuItems = [
    {name: 'Find Local Subs', functionName: 'getSubInfo'}
  ];
  spreadsheet.addMenu('Subcontractors', menuItems);
}

/**
 * A custom function that converts meters to miles.
 *
 * @param {Number} meters The distance in meters.
 * @return {Number} The distance in miles.
 */
function metersToMiles(meters) {
  if (typeof meters != 'number') {
    return null;
  }
  return meters / 1000 * 0.621371;
}

/**
 * A custom function that gets the driving distance between two addresses.
 *
 * @param {String} origin The starting address.
 * @param {String} destination The ending address.
 * @return {Number} The distance in meters.
 */
function drivingDistance(origin, destination) {
  var directions = getDirections_(origin, destination);
  return directions.routes[0].legs[0].distance.value;
}

function drivingDistanceMiles(origin,destination){
  var distMeters = drivingDistance(origin,destination);
  return metersToMiles(distMeters);
}

//start the program and ask for location
function getSubInfo(){
  var job = Browser.inputBox('Job',
                             'Please enter the job name' +
                             ' (for example, "Hamilton WWTP"):',
                             Browser.Buttons.OK_CANCEL);
  if (job == 'cancel') {
    return;
  }  
  var jobLocation = Browser.inputBox('Job Site Location',
                                     'Please enter the address of the job site as accurately as possible' +
                                     ' (for example, "2 Rosewood dr, Wilder, Kentucky"):',
                                     Browser.Buttons.OK_CANCEL);
  if (jobLocation == 'cancel') {
    return;
  } 
  var maxDistance = Browser.inputBox('Max Distance',
                                     'Please enter a maximum allowable distance from a job site that a sub can be' +
                                     '(for example, "50")',
                                     Browser.Buttons.OK_CANCEL);
  if(maxDistance == 'cancel'){
    return
  }
  findSubs(job,jobLocation,maxDistance);
}

function findSubs(job,jobLocation,maxDistance){
  var data = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  var filteredData = new Array;
  var numFiltered = 0;
  for (row = 0, len = SpreadsheetApp.getActiveSheet().getLastRow(); row < len; row++) {
    var subLocation = data[row][26] + ", " + data[row][27];
      if (drivingDistanceMiles(subLocation,jobLocation) < maxDistance){
        for(currentCol = 0; currentCol < 32; currentCol++){
          filteredData[numFiltered][currentCol] = data[row][currentCol];
        }
        numFiltered++;
      }
  }
  buildSubSheet(job,jobLocation,filteredData,numFiltered);
}

function buildSubSheet(job,jobLocation,filteredData,numFiltered){
  var ss = SpreadsheetApp.getActive();
  var infoSheet = spreadsheet.getSheetByName('2012');
  infoSheet.activate();
  var sheetName = job + " Subs";
  var subsSheet = spreadsheet.getSheetByName(sheetName);
  if (directionsSheet) {
    directionsSheet.clear();
    directionsSheet.activate();
  } else {
    directionsSheet =
        spreadsheet.insertSheet(sheetName, spreadsheet.getNumSheets());
  }
  var sheetTitle = "Subcontractors for " + job;
//  var headers = [
//    [sheetTitle, '', ''],
//    ['Step', 'Distance (Meters)', 'Distance (Miles)']
//  ];
  subsSheet.activate();
  range = subSheet.getRange(2,1,numFiltered,33);
  range.setValues(filteredData);
}
谢谢,
光线查看第99行,其中报告了错误:

      filteredData[numFiltered][currentCol] = data[row][currentCol];
您正在为数组数组(也称为二维数组)赋值。在第93行,您定义了:

  var filteredData = new Array;
所以你有一个数组要开始,很好。但在将值分配给子数组之前,首先需要以某种方式对其进行定义。一种方法是在循环中进行,但由于您是通过currentCol进行索引,因此应该在currentCol递增的范围内进行索引。比如:

  for (row = 0, len = SpreadsheetApp.getActiveSheet().getLastRow(); row < len; row++) {
    var subLocation = data[row][26] + ", " + data[row][27];
      if (drivingDistanceMiles(subLocation,jobLocation) < maxDistance){
        filteredData[numFiltered] = new Array;
        ...
您正在检查undefined,可以改为检查directions.length==0,这将更符合逻辑,但是您实际上没有设置dist=0,因此在第二个if语句中可能会未定义dist。由于undefined和0不相等,因此计算结果为false。没有错误,但它可能没有做您认为应该做的事情

最好先设置默认值,然后继续计算:

  var dist = 0;   // set the default value first
  if (typeof directions.routes[0] != 'undefined'){
    dist = directions.routes[0].legs[0].distance.value  // no 'var' here
  }
当有路由时,语句dist=100000;将更改方向。路线[0]。支腿[0]。距离。值,将返回。这是有道理的,因为你试图取消承包商将工地作为其地址的情况。但是,当没有路由时,设置dist=0对返回的方向没有任何影响。相反,您可以嵌套决策,而不必担心决策之外的dist=0

  if (typeof directions.routes.length != 0){  // we have a route
    var dist = directions.routes[0].legs[0].distance.value

    if (dist == 0 && origin == ', ') {
     dist = 100000;   // dest = origin => disqualify
    }
  }
  ...
  if (typeof directions.routes.length != 0){  // we have a route
    var dist = directions.routes[0].legs[0].distance.value

    if (dist == 0 && origin == ', ') {
     dist = 100000;   // dest = origin => disqualify
    }
  }
  ...