首页 > 解决方案 > Google Apps 脚本 - 仍在努力循环遍历行

问题描述

我仍在努力理解循环。

我有一个脚本,可以计算两个地址之间的公里距离。此时它只计算第 12 行的距离,并将结果放在 C 列第 12 行。

Start           End           Total km's      
address one     address two   16,283           

代码(在网上找到):

function GOOGLEMAPS() {

  var start_address = SpreadsheetApp.getActiveSheet().getRange('A12').getValue();
  var end_address = SpreadsheetApp.getActiveSheet().getRange('B12').getValue();

  var mapObj = Maps.newDirectionFinder();
  mapObj.setOrigin(start_address);
  mapObj.setDestination(end_address);
  var directions = mapObj.getDirections();

  var getTheLeg = directions["routes"][0]["legs"][0];

  var meters = getTheLeg["distance"]["value"];

  var keerduizend = meters / 1000;

  SpreadsheetApp.getActiveSheet().getRange('C12').setValue(keerduizend);

}

最终的结果应该是它可以计算所有放在工作表中的距离:

A               B             C
Start           End           Total km's      
address one     address two   16,283    
address two     address one   16,283    
address three   address four  16,283    
address five    address six   16,283    

                Total        SUM(C12:C15)

如果有 4 个地址或 40 个地址,用户应该能够添加行(在带有地址的最后一行和带有总计的行之间。由于我仍在努力理解循环,我不知道如何实现这个。

有人可以向我解释如何实现这一目标吗?

编辑

感谢 Diego 脚本的第一部分有效:

function GOOGLEMAPS() {

  var sheet = SpreadsheetApp.getActiveSheet();
  var start_addresses = sheet.getRange('B12:B26').getValues(); // [["address one"], ["address two"], ["address three"], ["address five"]]
  var end_addresses = sheet.getRange('D12:D26').getValues(); // [["address two"], ["address one"], ["address four"], ["address six"]]

  var distances = []; // This will store all of the distances

    for (var i = 0; i < start_addresses.length; i++) {
    var mapObj = Maps.newDirectionFinder();
    if (start_addresses[i][0] != "" && end_addresses[i][0] != "") {
      mapObj.setOrigin(start_addresses[i][0]);
      mapObj.setDestination(end_addresses[i][0]);
      var directions = mapObj.getDirections();

      var getTheLeg = directions["routes"][0]["legs"][0];

      var meters = getTheLeg["distance"]["value"];

      var keerduizend = meters / 1000;

      distances.push([keerduizend]);
    }
  }

  sheet.getRange('E12:E26').setValues(distances);

}

仍然得到一个错误

The number of rows in the data does not match the number of rows in the range. The data has 3, but the range has 15. (line 30, file 'Code')

但我会先尝试自己解决这个问题。

标签: loopsgoogle-apps-script

解决方案


要读取“A12:B15”范围内的所有值,您应该使用.getValues(). 如果您查看文档,您会看到它返回一个二维数组。数组中的第一个元素是行,第二个元素是列。像这样的东西:

       0      1
0 [ ["A-1", "B-1"] ]
1 [ ["A-2", "B-2"] ]

所以A-1的地址是[0][0];A-2的地址是[1][0];B-1的地址是[0][1];B-2的地址是[1][1]。您可以使用for 循环来读取每个地址的值。查看下面的代码并尝试在纸上弄清楚,然后在编辑器中运行它。

function test_forLoop() {
  var data = [["A-1", "B-1"], ["A-2", "B-2"]];
  for (var rowIndex = 0; rowIndex < data.length; rowIndex++) {
    for (var columnIndex = 0; columnIndex < data[rowIndex].length; columnIndex++) {
      Logger.log(data[rowIndex][columnIndex]); // Will print: "A-1", "B-1", "A-2", "B-2"
    }
  }
}

这是一个非常简短的介绍,但让我们回到您的代码。您可以调用.getValues()A 列范围和 B 列范围,然后遍历这些值以计算各种距离。最后,您可以使用.setValues()将结果打印到 C 列。

function GOOGLEMAPS() {

  var sheet = SpreadsheetApp.getActiveSheet();
  var start_addresses = sheet.getRange('A12:A15').getValues(); // [["address one"], ["address two"], ["address three"], ["address five"]]
  var end_addresses = sheet.getRange('B12:B15').getValues(); // [["address two"], ["address one"], ["address four"], ["address six"]]

  var distances = []; // This will store all of the distances

  for (var i = 0; i < start_addresses.length; i++) {
    var mapObj = Maps.newDirectionFinder();
    if (start_addresses[i][0] != "" && end_addresses[i][0] != "") {
      mapObj.setOrigin(start_addresses[i][0]);
      mapObj.setDestination(end_addresses[i][0]);
      var directions = mapObj.getDirections();

      var getTheLeg = directions["routes"][0]["legs"][0];

      var meters = getTheLeg["distance"]["value"];

      var keerduizend = meters / 1000;

      distances.push([keerduizend]);
    } else {
      distances.push([null]);
    }
  }

  sheet.getRange('C12:C15').setValues(distances);

}

有多种方法可以做到这一点,但为了帮助您更容易理解它,我选择对您所写的内容进行尽可能少的更改。如果您理解它,那么请继续考虑如何改进它。例如,如果您同时选择 A 列和 B 列 ( sheet.getRange('A12:B15')) 会怎样?


推荐阅读