如何在Google Spreadsheets中搜索和查找行的坐标

时间:2013-06-19 16:35:29

标签: google-apps-script google-sheets

我一直在寻找相当长的一段时间,所以希望没有人问过这个问题。

我有一个包含两张表的Google电子表格,一张包含表单提交的数据库,另一张用户可以一次一个地与提交内容进行交互。

基本上我希望用户能够对提交内容进行更改,并将其保存回原始工作表中的相同行。

我有代码发送更改,但我无法弄清楚如何获取正确行的坐标:

function saveChanges() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var source = ss.getSheets()[0];
 var destination = ss.getSheets()[1];

 var range = source.getRange("A40:BL40");

  // Find coordinates of the row where value of cell A40 matches a cell in A:A in second spreadsheet

 // This copies the data in A40:BL40 in the source sheet to
 // D4:F6 in the second sheet
 range.copyValuesToRange(destination, 1, 64, 16, 16);
}

此时数据刚刚写入坐标" 1,64,16,16"它只指向当前空行 - 理想情况下我将其更改为具有正确坐标的变量。

单元格A40的值是一个唯一的ID,非常适合搜索第二张,但我无法弄清楚如何。

我对Javascript很新,所以任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

要在表单响应表中找到匹配值,您必须遍历该范围才能找到匹配项。有很多方法可以做到,我会展示一对。

以下是saveChanges()函数的一个版本,该函数将从目标表中获取所有数据,查看其列A以查找A40中的值,然后更新该行中的数据

function saveChanges() {
  var uniqueIdColIndex = 0;  // Col "A" has unique ID, is element 0 in row array

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var source = ss.getSheets()[0];
  var destination = ss.getSheets()[1];

  var sourceData = source.getRange("A40:BL40").getValues();
  var destData = destination.getDataRange().getValues();

  // Find coordinates of the row where value of cell A40 matches a cell in A:A in second spreadsheet
  for (var rowIndex=0; rowIndex < destData.length; rowIndex++) {
    if (sourceData[0][uniqueIdColIndex] == destData[rowIndex][uniqueIdColIndex]) {
      // Found our match
      destination.getRange(rowIndex+1,1,sourceData.length,sourceData[0].length)
                 .setValues(sourceData);
      break; // Done, exit loop
    }
  }
}

这是另一种方法。这次,我们不会读取目标表中的所有数据,只读取A列中的信息。为了能够利用数组查找方法,需要通过.getValues()检索二维数组首先 - 所以我们使用辅助函数来做到这一点。 (我正在使用this answer中的transpose()函数。)

function saveChanges() {
  var uniqueIdColIndex = 0;  // Col "A" has unique ID, is element 0 in row array

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var source = ss.getSheets()[0];
  var destination = ss.getSheets()[1];

  var sourceData = source.getRange("A40:BL40").getValues();
  // Get column A from destination sheet
  var destDataTrans = transpose(destination.getRange(1, 1, destination.getLastRow(),1).getValues());

  // Find coordinates of the row where value of cell A40 matches a cell in A:A in second spreadsheet
  var destRow = destDataTrans[0].indexOf(sourceData[0]) + 1;  // +1 to adjust to spreadsheet rows

  if (destRow > 0) {
    // Found our match
    destination.getRange(destRow,1,sourceData.length,sourceData[0].length)
               .setValues(sourceData);
  }
}

第二种方法的代码行数较少,但应该比第一种方法慢一些,因为transpose()函数在使用.indexOf()执行搜索之前触及了A列中的每个元素。 (第一种方法在适当的位置进行搜索,并在找到匹配后退出,因此实际上做的工作较少。)

在这两个示例中,我都试图尽可能地限制对谷歌服务的调用。或者,您可以从搜索循环内的电子表格中读取信息,这会慢得多,但会避免保持基于0的数组与基于1的行和列对齐所需的+1 / -1心理体操。