比较2个不同的Google表格中的4个不同的列

时间:2019-03-27 13:37:09

标签: javascript arrays google-apps-script google-sheets

我正在尝试比较2个Google表格中的数据。每个工作表都有一个列作为标识符(sheet1:H和sheet2:C),如果这些匹配,那么我想将sheet1:I更改为sheet2:E中的值。我正在运行此代码,但没有错误。虽然没有用。

我试图看到类似的帖子来解决这个问题,但是它们似乎都缺少比较我正在使用的不同列方法的功能。

function changestatus() {
  // gets spreadsheet A and the range of data
  ssA = SpreadsheetApp.openById('IDHERE');
  sheetA = ssA.getSheetByName('Sheet1');
  dataA = sheetA.getRange('H2:H').getValues();
  dataD = sheetA.getRange('I2:I').getValues();

  // gets spreadsheet B and the range of data
  ssB = SpreadsheetApp.openById('IDHERE');
  sheetB = ssB.getSheetByName('responses');
  dataB = sheetB.getRange('C2:C').getValues();
  dataC = sheetB.getRange('E2:E').getValues();

  for (var i = 0; i > sheetA.getLastRow(); i++) {
    if (dataA[1][i] == dataB[1][i] && dataC[1][i] != dataD[1][i]){
      var value = sheetA.getRange(i+1, 2).getValue(dataD);
      sheetB.getRange(i+1, 2).setValue(value);
    } // end if
  } // end i

工作表文件的开始结果如下:

第1张
H:(ID)1 I :(等级)通过

表2
C:(ID)1 E :(等级)失败

后功能:

第1张
H:(ID)1 I :(等级)失败

1 个答案:

答案 0 :(得分:1)

@tehhowch是正确的;您需要查看JavaScript比较运算符,循环语法,Range#getValues返回的对象格式以及如何访问JavaScript数组索引。所有这些都会导致您的代码问题,但是我们可以在这方面提供更多帮助是合理的。

循环语法
这是个简单的。代替“ i> sheetA.getLastRow()”,它应显示为i < sheetA.getLastRow()。 i从零开始,在每个循环结束时其值增加一;因此,您希望循环处理所有小于最后一行值的i值。

数组值
getValues返回一个二维数组,但是IF语句失败,因为该数组的值是从前向后的。

例如,它应该是dataA[i][0]而不是“ dataA [1] [i]”。这里有两个变化:
1-“ i”移到数组值的前半部分(“行”值);和
2-数组值的后半部分为[0](不是“ [1]”)。这是因为每个变量只有一列宽。例如,dataA仅返回列H的值; dataB,dataC和dataD同样如此-它们都只返回一列的值。

问题排查
您如何判断IF语句是否有问题?它“看起来”确定。一种方法是显示(或记录)要返回的值。 我使用Logger.log()(还有其他选项)在脚本编辑器中的“查看,日志”下显示信息。每次运行脚本时,“ Logger”语句都会更新,您可以检查其值。

例如,您可以在第13行(循环之前)插入此代码,以检查数据变量的某些值。
Logger.log("dataA[1][0] = "+dataA[1][0]);
该行将显示:“ dataA [1] [0] = 2”。这是一个有效的结果,但是您可能会注意到它报告的ID = 2,但是,例如,您期望的是ID = 1的结果。

因此将行更改为:
Logger.log("dataA[1][1] = "+dataA[1][1]);
此行显示“ dataA [1] [1] =未定义”。好,肯定有问题。

所以,让我们尝试:
Logger.log("dataA[0][0] = "+dataA[0][0]);
该行显示“ dataA [0] [0] = 1”。现在更像它了。

您可以使Logger变长或变短;例如,您可能需要一行评估变量的结果。因此记录器可能看起来像这样:
Logger.log("dataA[0][0] = "+dataA[0][0]+", dataB[0][0] = "+dataB[0][0]+", dataC[0][0] = "+dataC[0][0]+", dataD[0][0] = "+dataD[0][0]);
它会返回:
“ dataA [0] [0] = 1,dataB [0] [0] = 1,dataC [0] [0] =失败,dataD [0] [0] =通过”。
这可能确认您走在正确的轨道上,或者您需要进一步调试

失败的IF语句
原始行=“(dataA [1] [i] == dataB [1] [i] && dataC [1] [i]!= dataD [1] [i])”
更正的行= (dataA[i][0] == dataB[i][0] && dataC[i][0] != dataD[i][0])

更新工作表1上的结果
这里的代码是:
var value = sheetA.getRange(i+1, 2).getValue(dataD);
sheetB.getRange(i+1, 2).setValue(value);

这令人困惑,并使两件事变得复杂。
1-值只需要是“ sheet2:E中的值-这在IF语句中:dataC[i][0]。所以value = dataC[i][0]
2-目标是“将sheet1:I更改为sheet2:E中的值”。您已经拥有了价值,所以现在将重点放在sheet1:I上。 有时,定义范围更简单,然后在第二行中更新该范围的值。

  • 目标工作表为sheetA;
  • 目标行是:i + 1(正确);
  • 目标列是:I(或第9列)。

所以var range = sheetA.getRange(i+2, 9); 您可以使用“记录器”进行检查:
Logger.log("range = "+range.getA1Notation());可能会返回“范围= I2”。

然后更新值: range.setValue(value);

有意义的变量名
帮助(很多)使用有意义的变量名。例如,原始代码使用:
“ dataA” = Sheet1,H列(包含ID);因此可能是“ data1_H”甚至是“ targetID”。
“ dataD” = Sheet1,第I栏(包含等级);因此可能是“ data1_I”或targetGrade。
“ dataB” = Sheet2,列C(包含ID),因此可能是“ data2_C”或sourceID。
“ dataC” = Sheet2,E列(包含等级);因此可能是“ data2_E”或sourceGrade。


更改摘要

function so_changestatus() {
  // gets spreadsheet A and the range of data
  ssA = SpreadsheetApp.openById('IDHERE');
  sheetA = ssA.getSheetByName('Sheet1');
  dataA = sheetA.getRange('H2:H').getValues();
  dataD = sheetA.getRange('I2:I').getValues();

  // gets spreadsheet B and the range of data
  ssB = SpreadsheetApp.openById('IDHERE');
  sheetB = ssB.getSheetByName('responses');
  dataB = sheetB.getRange('C2:C').getValues();
  dataC = sheetB.getRange('E2:E').getValues();


  for (var i = 0; i < sheetA.getLastRow(); i++) {
    if (dataA[i][0] == dataB[i][0] && dataC[i][0] != dataD[i][0]){
      var value = dataC[i][0];
      var range = sheetA.getRange(i+2, 9);
       range.setValue(value);
    } // end if
  } 
}

更新-2019年4月1日
SheetA与SheetB上的ID逐行不匹配
原始代码是根据ID在逐行匹配的基础上编写的。不是这种情况。因此,需要对代码进行更改,以测试SheetB上是否存在SheetA上的ID,然后测试各自的状态。

[indexof] Docs reference对sheetB上的sheetA ID进行评估。

在这段代码中,我还借此机会使数据范围的变量名更有意义。

还请注意:当i小于最后一行减一“ i <(lastrow-1);”时,循环继续。这是必需的,因为第一行是标题,并且数据范围从第2行开始,因此数据行的数量将为“最后一行减一”(以允许出现标题行)。

function ejb2so_changestatus() {
  // gets spreadsheet A and the range of data

  //  ssA = SpreadsheetApp.openById('IDHERE');
  ssA = SpreadsheetApp.getActive();
  sheetA = ssA.getSheetByName('Sheet1');
  dataA_ID = sheetA.getRange('H2:H').getValues();
  data_Status = sheetA.getRange('I2:I').getValues();
  //Logger.log("DEBUG: H3 = "+dataA_ID[4][0]+", I3 = "+data_Status[4][0]);//DEBUG

  // gets spreadsheet B and the range of data
  //ssB = SpreadsheetApp.openById('IDHERE');
  ssB = SpreadsheetApp.getActive();
  sheetB = ssB.getSheetByName('Responses');
  dataB_ID = sheetB.getRange('C2:C').getValues();
  dataB_Status = sheetB.getRange('E2:E').getValues();
  // Logger.log("DEBUG: C3 = "+dataB_ID[0][0]+", E3 = "+dataB_Status[0][0]);//DEBUG

  var lastrow = sheetA.getLastRow()
  // Logger.log("DEBUG: sheetA last row = "+lastrow);//DEBUG

  // Flatten the array
  var dataB_IDFlat = dataB_ID.map(function(row) {
    return row[0];
  });

  //Loop through values on sheetA; check if they exist on sheetB
  for (var i = 0; i < (lastrow - 1); i++) {
    var A_ID = dataA_ID[i][0];
    // Logger.log("DEBUG: id = "+A_ID);//DEBUG

    // assign variable to return value index
    var result = dataB_IDFlat.indexOf(A_ID);

    if (result != -1) {
      // it's there 
      // Logger.log("DEBUG: i: "+i+", ID: "+A_ID+", it's there"+", result#: "+result);//DEBUG
      // Logger.log("DEBUG: Sheet1 status: "+data_Status[i][0]+" Vs Sheet2 status = "+dataB_Status[result][0]);//DEBUG

      // compare status from sheetsA to sheetB
      if (data_Status[i][0] != dataB_Status[result][0]) {
        // Logger.log("DEBUG: status change to: "+dataB_Status[result][0]);//DEBUG
        var range = sheetA.getRange(i + 2, 9);
        //Logger.log("DEBUG: value = "+value);//DEBUG
        //Logger.log("DEBUG: range = "+range.getA1Notation());//DEBUG
        range.setValue(dataB_Status[result][0]);
      }
    } else {
      // it's not there
      // Logger.log("DEBUG: i: "+i+", ID: "+A_ID+", it's not there");//DEBUG
    }
  }
}

// Credit: Flatten array: https://stackoverflow.com/a/49354635/1330560