Javascript Google Sheets脚本中的距离未定义错误
好的,所以我试着制作一个程序,通过一个分包商列表和他们的数据,然后制作一个新的表格,填充附近的分包商 我遇到的问题是,当为分包商指定的位置与作业位置相同时,将返回一个错误。具体地说:“TypeError:无法将未定义的属性0.0设置为。”在脚本编辑器的执行记录中,我在代码失败之前得到了此错误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
[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
}
}
...