【问题标题】:Compare two columns for matches and pull the adjacent value for each match比较两列的匹配项并拉取每个匹配项的相邻值
【发布时间】:2020-01-04 19:06:20
【问题描述】:

我正在尝试比较两个不同工作表上两列的值(工作表 A 上的 G 列和工作表 B 上的 J 列)。对于每个匹配项,我希望脚本将值从工作表 A 的 N 列复制到工作表 B 的 K 列。

我花了好几天的时间试图弄清楚,但似乎无法正确解决。这是我尝试过的一些代码 -

function CopyTCEmailImportV6() {
// gets spreadsheet A and the range of data
var ssA = SpreadsheetApp.getActiveSpreadsheet();
var sheetA = ssA.getSheetByName('(Test) E-mail List');
var dataA = sheetA.getRange('G:N').getValues();

// gets spreadsheet B and the range of data
var sheetB = ssA.getSheetByName('Ticket Counts (Master)');
var dataB = sheetB.getRange('J:K').getValues();

// loops through column A of spreadsheet A & B and compares
for(var i = 0; i < sheetA.getLastRow(); i++){
  if (dataA[i][0] === dataB[i][0]){
values.push([dataA[i][7]]);
} else {
values.push([""]);
}
}
sheetB.getRange(1, 11, values.length, 
values[0].length).setValues(values);
};

非常感谢任何帮助!

Sheet A - I'd like match the value in Column G with sheet B, and if there's a match copy the corresponding value in Column N

The Column G values from Sheet A should be matched to the Column J values of Sheet B and if there's a match paste the copied values onto the same row in column K. In this case, "25" should be copied into cell K11.

这是完成的代码,以防万一它可以帮助某人解决问题 -

function CopyTCEmailImportV6() {
  // gets spreadsheet A and the range of data
  var ssA = SpreadsheetApp.getActiveSpreadsheet();
  var sheetA = ssA.getSheetByName('(Test) E-mail List');
  var dataAa = sheetA.getRange('G2:N' + sheetA.getLastRow()).getValues(); // Modified
var dataA = dataAa.reduce(function(ar, n) {
  if (n[7]) ar.push(n)
  return ar;
}, []);

  // gets spreadsheet B and the range of data
  var sheetB = ssA.getSheetByName('Ticket Counts (Master)');
  var dataB = sheetB.getRange('J2:K' + sheetB.getLastRow()).getValues(); // Modified

  // Below script was also added.
  var obj = dataA.reduce(function(o, e) {
    o[e[0]] = e[7];
    return o;
  }, {})
  var values = dataB.map(function(e, i) {return e[0] in obj ? [obj[e[0]]] : [e[1]]});
  sheetB.getRange(2, 11, values.length, values[0].length).setValues(values);
};

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:
    • 您想比较工作表 A (Test) E-mail List 上的列“G”和工作表 B Ticket Counts (Master) 上的列“J”的值。
      • 要比较的行号在工作表 A 上的“G”列和工作表 B 上的“J”列之间是相同的。
    • 当工作表 A 上的“G”列和工作表 B 上的“J”列的值相同时,您希望将工作表 A 上的“N”列的值复制到“K”列" 在 B 表上。
    • 您希望使用 Google Apps 脚本实现此目的。

    如果我的理解是正确的,那么这个修改呢?

    修改点:

    • 请将for (var i = 0; i &gt; sheetA.getLastRow(); i++) {修改为for (var i = 0; i &lt; sheetA.getLastRow(); i++) {
      • 在这种情况下,for 循环不起作用。
    • 请将if (dataA[1][i] === dataB[1][i]){修改为if (dataA[i][0] == dataB[i][0]) {
      • 例如,在您的情况下,单元格“G1”和“G2”的值可以分别通过dataA[0][0]dataA[1][0] 检索。
    • 当创建放入Spreadsheet的数组并使用setValues()放入数组时,比在for循环中使用setValue()的方法可以降低处理成本。

    修改脚本:

    当你的脚本被修改时,请进行如下修改。

    从:
    for(var i = 0; i > sheetA.getLastRow(); i++){
      if (dataA[1][i] === dataB[1][i]){
      var value = sheetA.getRange(i+1, 8).getValue();
      array is 0
      sheetB.getRange(i+1, 2).setValue(value);
    } // end if;
    }; // end i
    };
    
    到:
    var values = [];
    for (var i = 0; i < sheetA.getLastRow(); i++) {
      if (dataA[i][0] == dataB[i][0]) {
        values.push([dataA[i][7]]);
      } else {
        values.push([""]);
      }
    }
    sheetB.getRange(1, 11, values.length, values[0].length).setValues(values);
    

    var values = dataA.map(function(e, i) {return e[0] === dataB[i][0] ? [dataA[i][7]] : [""]});
    sheetB.getRange(1, 11, values.length, values[0].length).setValues(values);
    

    参考资料:

    如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

    编辑:

    从您共享的图像中,我可以知道工作表 A 上“G”列的值是随机排列的。而且,似乎“G”列的每个值都只是“G”列中的一个。通过这个,我修改了上面的脚本。

    修改脚本:

    function CopyTCEmailImportV6() {
      // gets spreadsheet A and the range of data
      var ssA = SpreadsheetApp.getActiveSpreadsheet();
      var sheetA = ssA.getSheetByName('(Test) E-mail List');
      var dataA = sheetA.getRange('G2:N' + sheetA.getLastRow()).getValues(); // Modified
    
      // gets spreadsheet B and the range of data
      var sheetB = ssA.getSheetByName('Ticket Counts (Master)');
      var dataB = sheetB.getRange('J2:K' + sheetB.getLastRow()).getValues(); // Modified
    
      // Below script was also added.
      var obj = dataA.reduce(function(o, e) {
        o[e[0]] = e[7];
        return o;
      }, {})
      var values = dataB.map(function(e, i) {return e[0] in obj ? [obj[e[0]]] : [""]});
      sheetB.getRange(2, 11, values.length, values[0].length).setValues(values);
    };
    

    【讨论】:

    • 谢谢 - 这帮了很多忙!我现在收到错误“无法从未定义中读取属性“0””,我猜这是因为我正在提取的数据中有未定义/空白单元格。我更新了我的问题以包含工作表 A 和工作表 B 的示例,以便您更好地了解我想要做什么。
    • @Joey 感谢您的回复。我带来的不便表示歉意。我通过想象您当前的情况来更新我的答案。那你能确认一下吗?如果这不能解决您的问题,您能否提供一个示例电子表格,通过包含您当前的脚本来复制您的问题?借此,我想确认一下。
    • 感谢@Tanaike!这正是我一直在寻找的。我将 [""] 替换为 [e[1]] 以便我可以将工作表 A 上没有匹配的任何值保留在适当的位置。我确实有最后一个问题 - 目前,如果 N 列中的工作表 B 上有一个空值,它会覆盖工作表 A 上匹配的单元格中的空值。有没有办法编辑脚本以便它跳过空值工作表 B 上的 N 列并且不会覆盖工作表 A 上的列?感谢您的所有帮助!
    • 完成 - 我能够解决我的问题的最后一部分。我添加了完成的脚本。感激不尽!
    • @Joey 感谢您的回复和其他信息。我很高兴你的问题得到了解决。也谢谢你。
    【解决方案2】:

    您的 for 循环似乎很糟糕,

    for(var i = 0; i > sheetA.getLastRow(); i++){
    

    > 应该是一个

    【讨论】:

      猜你喜欢
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 2016-12-23
      • 2010-11-26
      相关资源
      最近更新 更多