【问题标题】:Paste values from one Google Sheet to another and remove duplicates based on ID column将值从一个 Google Sheet 粘贴到另一个,并根据 ID 列删除重复项
【发布时间】:2018-09-12 06:27:31
【问题描述】:

我的情况与question 中描述的情况类似:两个工作表,输入数据使用 importxml 函数进入 Feed 工作表和一个 Data由于设置为每天运行的脚本,新行被复制的工作表。

但是,当前脚本正在创建每日副本。因此,我想修改上述问题中提供的答案,以便脚本检查 F 列上的 ID,并仅复制具有新 ID 的行。

我应该如何将下面创建哈希的部分更新为在 F 列上查找 ID 的部分?我的行也是一致的,所以假设我可以在最后删除相关的代码行是否正确?

可通过here 获取示例 Google 表格。

function appendUniqueRows() {
  var ss = SpreadsheetApp.getActive();
  var sourceSheet = ss.getSheetByName('Get Data');
  var destSheet = ss.getSheetByName('Final Data');

  var sourceData = sourceSheet.getDataRange().getValues();
  var destData = destSheet.getDataRange().getValues();

  // Check whether destination sheet is empty
  if (destData.length === 1 && "" === destData[0].join('')) {
    // Empty, so ignore the phantom row
    destData = [];
  }

  // Generate hash for comparisons
  var destHash = {};
  destData.forEach(function(row) {
    destHash[row.join('')] = true; // could be anything
  });

  // Concatentate source rows to dest rows if they satisfy a uniqueness filter
  var mergedData = destData.concat(sourceData.filter(function (row) {
    var hashedRow = row.join('');
    if (!destHash.hasOwnProperty(hashedRow)) {
      // This row is unique
      destHash[hashedRow] = true;   // Add to hash for future comparisons
      return true;                  // filter -> true
    }
    return false;                   // not unique, filter -> false
  }));

  // Check whether two data sets were the same width
  var sourceWidth = (sourceData.length > 0) ? sourceData[0].length : 0;
  var destWidth = (destData.length > 0) ? destData[0].length : 0;
  if (sourceWidth !== destWidth) {
    // Pad out all columns for the new row
    var mergedWidth = Math.max(sourceWidth,destWidth);
    for (var row=0; row<mergedData.length; row++) {
      for (var col=mergedData[row].length; col<mergedWidth; col++)
        mergedData[row].push('');
    }
  }

  // Write merged data to destination sheet
  destSheet.getRange(1, 1, mergedData.length, mergedData[0].length)
           .setValues(mergedData);
}

我是这个 Google Apps 脚本世界的新手,所以如果我遗漏了任何重要信息,请告诉我。提前感谢您的帮助。

【问题讨论】:

  • 我可以问你关于你的问题吗? 1. 共享电子表格中的脚本与您的问题中的脚本有什么区别?因为在您的共享电子表格中找不到Get DataFinal Data 的工作表。 2. 当Feed 工作表中的值被复制到Data 工作表中时,您希望不重复ID。我的理解正确吗?
  • 感谢您查看@Tanaike。共享 Google 工作表上的脚本仅将行从 Feed 工作表复制到 Data 工作表,所以我想用我的问题中的类似内容替换它,只复制不是的新行已根据 F 列中的 ID 保存到 Data 工作表中。
  • 感谢您的回复。根据您的评论,我发布了答案。你能确认一下吗?如果我误解了你的问题,请告诉我。我想修改它。
  • 我的回答是否向您展示了您想要的结果?你能告诉我吗?这对我学习也很有用。如果这可行,与您有相同问题的其他人也可以将您的问题作为可以解决的问题。如果您对我的回答有疑问,请随时告诉我。我想学习解决你的问题。

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


【解决方案1】:
  • 您想要将值从“Feed”表复制到“Data”表。
  • 复制值时,您只想复制未包含在“数据”表中的新值。
  • 您想使用“F”列的值选择新值。

如果我对你的问题的理解是正确的,那么这个修改怎么样?在此修改中,我修改了您共享电子表格中的脚本。

修改点:

  • 在您的脚本中,“Feed”表的所有值都被复制到“Data”表中。因此,为了只选择新值,我使用了以下流程。
    1. 从“F”列检索值。这用于选择新值。
    2. 使用“F”列中的值检索新值。
    3. 将新值放入“数据”表。

反映以上流程的脚本如下。

修改后的脚本:

从:

这是您在共享电子表格中的脚本。请将此脚本修改为以下。

function Copy() {
  var sss = SpreadsheetApp.openById('#####'); // this is your Spreadsheet key
  var ss = sss.getSheetByName('Feed'); // this is the name of your source Sheet tab
  var range = ss.getRange('A3:H52'); //assign the range you want to copy
  var data = range.getValues();
  var tss = SpreadsheetApp.openById('#####'); //replace with destination ID
  var ts = tss.getSheetByName('Data'); //replace with destination Sheet tab name
  ts.getRange(ts.getLastRow()+1, 1,50,8).setValues(data);// 49 value refers to number of rows, 8 to columns
}
至:
function Copy() {
  var sss = SpreadsheetApp.openById('#####'); // this is your Spreadsheet key
  var ss = sss.getSheetByName('Feed'); // this is the name of your source Sheet tab
  var range = ss.getRange('A3:H52'); //assign the range you want to copy
  var data = range.getValues();
  var tss = SpreadsheetApp.openById('#####'); //replace with destination ID
  var ts = tss.getSheetByName('Data'); //replace with destination Sheet tab name

  // Below script was added.
  var values = ts.getRange("F3:F").getValues().filter(String);
  var copiedValues = data.filter(function(e) {return !values.some(function(f){return f[0] == e[5]}) && e.filter(String).length > 0});
  ts.getRange(ts.getLastRow() + 1, 1, copiedValues.length, copiedValues[0].length).setValues(copiedValues);
}

【讨论】:

  • 感谢@Tanaike 的回答!我已经在 Google 工作表上运行了脚本,它似乎运行良好。我还在另一张具有不同提要的工作表上尝试过,其中 ID 列不同(E 列,而不是 F)并且列更多,但所有其他参数都相同,但这里脚本确实继续复制重复行。我更新了电子表格 ID、工作表范围和 Values 变量的范围。我是否需要更新脚本的任何其他部分才能使其正常工作?
  • @Filipe Zuluaga 感谢您的回复。我很高兴你的问题得到了解决。关于你的新问题,如果搜索的栏目不同,请修改var valuesF3:Fvar copiedValuese[5]e[5]5 表示“F”列。例如“E”栏,请分别修改为E3:Ee[4]。我对您的评论的理解正确吗?
  • 非常感谢您的及时回复。在其他工作表上也一切正常!我怀疑需要进行一些其他更改,例如您建议的更改,但我对代码的有限理解仅让我到目前为止。再次感谢!
  • @Filipe Zuluaga 很高兴您的问题得到了解决。也谢谢你。
猜你喜欢
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多