【问题标题】:How to use google scripts to check two google sheets, and move the duplicates to a new sheet?如何使用谷歌脚本检查两个谷歌工作表,并将重复项移动到新工作表?
【发布时间】:2020-01-03 05:02:36
【问题描述】:

我正在尝试做一些看似简单的事情。我有一张巨大的 20k 联系人表,其中有些联系人的电子邮件很糟糕。我已经编制了一个我想要提取的不良电子邮件列表,并想编写一个脚本,从“20k”列表中的“不良”列表中找到电子邮件,将每封不良电子邮件的整行复制到“新"(生成)表,然后从 20k 列表中删除该行。

一切正常,直到它需要检查重复项、复制它们并删除旧的(嵌套的 for 循环)。现在它会多次复制所有内容(是否重复),然后删除整个工作表。问题代码如下:

 // Find duplicates from the two sheets and move them to the "FindDupes" sheet
  var dupes = false;
  var dataMDS = sourceSheetMDS.getDataRange().getValues();
  var dataETR = sourceSheetETR.getDataRange().getValues();
  for (i = numETRRows; i >= 0; i--) {
    for (j = numMDSRows; j >= 0; j--) {
      if  (sourceSheetETR[i,1] == sourceSheetMDS[j,1]) {
        dupes = true;

        // Copy the desired rows to the FindDupes sheet
        for (var k = 1; k <= numMDSCols; k++) {
          var sourceRange = sourceSheetMDS.getRange(1,k,j);
          var nextCol = newSheet.getLastColumn() + 1;
          sourceRange.copyTo(newSheet.getRange(1,nextCol,j));
        }
        sourceSheetMDS.deleteRow(j);
      }
    }
  }

这是整个项目:

function findDuplicates() {

  // List the columns you want to check by number (A = 1)
  var CHECK_COLUMNS = [1];

  //Declare the Spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();  

  // Get the active sheet and info about it
  // Main Database Sheet
  var sourceSheetMDS = ss.getSheetByName("test");
  var numMDSRows = sourceSheetMDS.getLastRow();
  var numMDSCols = sourceSheetMDS.getLastColumn();

  // Get the active sheet and info about it
  // Emails To Rremove Sheet
  var sourceSheetETR = ss.getSheetByName("Emails to Remove");
  var numETRRows = sourceSheetETR.getLastRow();
  var numETRCols = sourceSheetETR.getLastColumn();

  // Create the sheet of duplicates
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var newSheet = ss.insertSheet("FindDupes");

  // Find duplicates from the two sheets and move them to the "FindDupes" sheet
  var dupes = false;
  var dataMDS = sourceSheetMDS.getDataRange().getValues();
  var dataETR = sourceSheetETR.getDataRange().getValues();
  for (i = numETRRows; i >= 0; i--) {
    for (j = numMDSRows; j >= 0; j--) {
      if  (sourceSheetETR[i,1] == sourceSheetMDS[j,1]) {
        dupes = true;

        // Copy the desired rows to the FindDupes sheet
        for (var k = 1; k <= numMDSCols; k++) {
          var sourceRange = sourceSheetMDS.getRange(1,k,j);
          var nextCol = newSheet.getLastColumn() + 1;
          sourceRange.copyTo(newSheet.getRange(1,nextCol,j));
        }
        sourceSheetMDS.deleteRow(j);
      }
    }
  }


  // Alert the user with the results
  if (dupes) {
    Browser.msgBox("Possible duplicate(s) found, moved, and deleted.");
  } else {
    Browser.msgBox("No duplicates found.");
  }
};

谢谢!

【问题讨论】:

  • 您的代码有什么问题 - 它没有按预期工作,您是否遇到任何错误?
  • 感谢您的回复!我对其进行了编辑以显示问题代码是什么,以及发生了什么。

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


【解决方案1】:

我不得不改变一些东西,因为我无法让它正常运行。

function findDuplicates() {

  // List the columns you want to check by number (A = 1)
  var CHECK_COLUMNS = [1];

  //Declare the Spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();  

  // Get the active sheet and info about it
  // Main Database Sheet
  var sourceSheetMDS = ss.getSheetByName("test");
  var numMDSRows = sourceSheetMDS.getLastRow();
  var numMDSCols = sourceSheetMDS.getLastColumn();

  // Get the active sheet and info about it
  // Emails To Rremove Sheet
  var sourceSheetETR = ss.getSheetByName("Emails to Remove");
  var numETRRows = sourceSheetETR.getLastRow();
  var numETRCols = sourceSheetETR.getLastColumn();
  
  // Create the sheet of duplicates
  var newSheet = ss.insertSheet("FindDupes");

  // Find duplicates from the two sheets and move them to the "FindDupes" sheet
  var dupes = false;
  var dataMDS = sourceSheetMDS.getDataRange().getValues().reverse();
  var dataETR = sourceSheetETR.getDataRange().getValues();
  var rowsToDelete = []
  dataETR.forEach(function (emailToRemoveRow) {
    var emailToRemove = emailToRemoveRow[0]
    dataMDS.forEach(function (dataRow, j) {
      var emailOfData = dataRow[0]
      if (emailToRemove == emailOfData) {
        dupes = true;

        // Copy the desired rows to the FindDupes sheet
        newSheet.appendRow(dataRow)
        rowsToDelete.push(j)
      }
    })
  })
  rowsToDelete.sort(function (a, b) {
   return b - a;
  }).forEach(function (rowIndex) {
     sourceSheetMDS.deleteRow(rowIndex);
  })


  // Alert the user with the results
  if (dupes) {
    Browser.msgBox("Possible duplicate(s) found, moved, and deleted.");
  } else {
    Browser.msgBox("No duplicates found.");
  }
};

我仍然有点困惑,因为 check_columns 没有被使用。那么电子邮件列到底在哪里呢?删除工作表的电子邮件是什么样的?上面的代码假设要删除的电子邮件只有一列,其中包含我们要删除的电子邮件,而测试表的第一列中有电子邮件。

【讨论】:

  • 听起来不是多余的,但非常感谢! check_column 应该用于主数据库表。在原始代码中,check_columns 将取代找到 1 的位置(对于 MDS)。这样,如果我需要检查名称是否重复,我可以轻松地将其更改为该列。要删除的电子邮件表只有一列,其中包含大量电子邮件,而大数据库有大量列,但只需要检查一个特定列。
  • 好的。嗯,这不应该太难添加。这个脚本对你有用吗?
  • 我同意,这将是一个小调整。好像离得太近了!!有没有办法从下到上检查它?它不断跳闸一个错误,说它超出了界限:那些行超出了界限。 (第 38 行,文件“代码”)。当我调试代码时,它说 j 等于零值。
  • 好的,我调整了它,所以它会自下而上检查它(reverse())。但还添加了几行来对要删除的行进行排序,以便它们也被自下而上地删除。我认为这应该可以解决越界错误,但仍然可能存在错误。
  • 你是个超级英雄。它几乎可以做所有事情。出于某种原因,它只导入每隔一个,删除非重复项,然后最后仍然超出范围。我正在尝试在您发送它时对其进行调整,但我从未见过您使用的策略!
【解决方案2】:

改变

if  (sourceSheetETR[i,1] == sourceSheetMDS[j,1]) {
        dupes = true;
...

if  (dataETR[i,1] == dataMDS[j,1]) {
        dupes = true;
...

解释:

您必须比较值而不是(不存在)工作表数组条目。

【讨论】:

  • 感谢您的回复,非常重要。我进行了更改,但现在它说没有找到重复项。我没有很多钱,但如果你帮我解决这个问题,我很乐意寄给你 20 美元让你吃点东西。
  • 我有点困惑。 CHECK_COLUMNS 变量的意义何在?它似乎没有被使用。
  • 检查列变量应该更容易指定检查哪些列。这样,如果我要检查电子邮件是否有重复项,那么我可以指定电子邮件列,如果我想检查姓名,那么我可以指定那个。
猜你喜欢
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多