Google脚本可删除电子表格中的重复行,并根据时间戳保留最新的条目

时间:2015-03-23 00:27:26

标签: google-apps-script timestamp google-sheets duplicates

我有一个由表单填充的Google电子表格,因此时间戳会自动添加到每行的第一列中。我有一个脚本可以删除电子表格中的重复行(5个特定列必须相同,因为它是重复的,而其他一些列则被忽略),但我想修改它,以便如果我有多个行相同人员的数据但具有不同的时间戳,脚本将保留最新的行。我该怎么做?谢谢!

/** removes duplicate rows in studentsheet **/
function removeDuplicates() {
  var newData = new Array();
  for(i in studentdata){
    var row = studentdata[i];
    var duplicate = false;
    for(j in newData){
      if(row[1] == newData[j][1] && row[2] == newData[j][2] && row[5] == newData[j][5] && row[9] == newData[j][9] && row[10] == newData[j][10]){
      duplicate = true; //first name, last name, grade, dad's first name, and mom's first name are the same
      }
    }
    if(!duplicate){
      newData.push(row);
    }
  }
  StudentSheet.clearContents();
  StudentSheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
  sortSheet(); //sorts sheet by 2 columns
}

4 个答案:

答案 0 :(得分:1)

这是一种不同的方法,将单个字符串中的所有列连接起来,将其保存为快速搜索的对象,如果你有一个大的表格可以帮助:

function deleteDuplicateRowsSaveRecent(){
  var verifiedRows = {},
      curretnRow = "",
      usedRows = [1, 2, 5, 9, 10];

  for( lin in studentdata){
    curretnRow = "";
    for( ind in usedRows )
      curretnRow += studentdata[ lin ][ usedRows[ ind ] ];

    if(verifiedRows[ curretnRow ]){
      if( studentdata[ lin ][ dateColumn ] > studentdata[ verifiedRows[ curretnRow ] ][ dateColumn ] ){
        studentSheet.deleteRow(verifiedRows[ curretnRow ])
        verifiedRows[ curretnRow ] = lin;
      }else
         studentSheet.deleteRow( lin );
    }
    else
      verifiedRows[ curretnRow ] = lin;
  }
}

没有经过测试,但希望你能得到逻辑。

答案 1 :(得分:1)

对数据进行排序,按照'测试重复数据进行分组'数据,然后按组内的日期降序,

从底部开始制作底行当前行。 当前行测试重复项'测试重复测试'排在上面。

如果上面一行的当前行重复,则删除当前行,将该行留在上面的行中以及更晚的日期。

如果没有重复,则上面的行成为当前行,并针对上面的行进行测试,如果重复则删除当前行,否则继续前进。

完成后,将电子表格中的现有数据替换为已正确排序的已修改数据。

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getSheetByName("Form Responses 1");
  // dataRange should not include headers
  var dataRange = s.getRange(2, 1, s.getLastRow() -1, s.getLastColumn())
  var data = dataRange.getValues();

  // Test for duplicate columns.
  // numbers below = column number; A=1 B=2 etc.
  var lName = 2;
  var fName = 3;
  var grade = 5;
  var dad = 9;
  var mom = 10;

  for( var i = 0; i < data.length; i++ ) {
    // add sortable date to beginning of rows
    data[i].unshift(Utilities.formatDate(data[i][0], "GMT", "yyyyMMddHHmmss"));
    // add sortable test for duplicates string in front of above date.
    // Placing the below in the order to be sorted by will save
    // a separate sort later
    data[i].unshift(
      data[i][lName].toLowerCase().trim() +
      data[i][fName].toLowerCase().trim() +
      data[i][grade].toString().trim() +
      data[i][dad].toLowerCase().trim() +
      data[i][mom].toLowerCase().trim()) 
  }
  // sort to group rows by test data
  data.sort();
  // reverse sort so latest date at top of each duplicate group.
  data.reverse();
  // test each row with one above and delete if duplicate.
  var len = data.length - 1;
  for( var i = len; i > 0; i-- ) {
    if(data[i][0] == data[i-1][0]) {
      data.splice(i, 1);
    }
  }
  // remove temp sort items from beginning of rows
  for( var i = 0; i < data.length; i++ ) {
    data[i].splice(0, 2);
  }
  // Current sort descending. Reverse for ascending
  data.reverse();
  s.getRange(2, 1, s.getLastRow(), s.getLastColumn()).clearContent();
  s.getRange(2, 1, data.length, data[0].length).setValues(data);
}

答案 2 :(得分:0)

在完成我之前的答案后,我认为这样做更好,我考虑了另一种方法,可以减少对现有代码的干扰。

您将第一个非重复数据从studentdata推送到新数组,因此如果studentdata按测试前的时间戳降序排序,那么推送的第一个非重复数据将是最新的。

在功能的最开始处放置以下内容应该实现

for( var i = 0; i < studentdata.length; i++ ) {
  // add sortable date to beginning of rows
  studentdata[i].unshift(Utilities.formatDate(studentdata[i][0], "GMT", "yyyyMMddHHmmss"));
  }
  studentdata.sort();
  studentdata.reverse();
  // remove temp sort date from beginning of rows
  for( var i = 0; i < studentdata.length; i++ ) {
    studentdata[i].splice(0, 1);
  }

答案 3 :(得分:-1)

我决定对提交日期列进行排序,以便将最近的日期放在最前面,然后运行我原来的重复删除脚本。它似乎工作。

 /** sorts studentsheet by most recent submission, by last name, and then by grade/role (columns) **/
        function sortSheet() {
          var ss = SpreadsheetApp.getActiveSpreadsheet();
          var sheet = ss.getSheetByName("Students");
          sheet.sort(1, false); //sorts column A by date of submission with most recent on top
          sheet.sort(3, true); // Sorts ascending (A-Z) by column C, last name
          sheet.sort(6, true); // Sorts ascending (A-Z) by column F, grade/role
          }

    function removeDuplicates(){
          var newData = new Array();
          for(i in studentdata){
            var row = studentdata[i];
            var duplicate = false;
            for(j in newData){
              if(row[1] == newData[j][1] && row[2] == newData[j][2] && row[5] == newData[j][5] && row[9] == newData[j][9] && row[10] == newData[j][10]){
              duplicate = true; //date of submission, first name, last name, grade, dad's first name, and mom's first name are the same
              }
            }
            if(!duplicate){
              newData.push(row);
            }
          }
          StudentSheet.clearContents();
          StudentSheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData); 
 }