简体   繁体   English

删除谷歌表格脚本中的过滤行(10000+行)

[英]Delete filtered rows in google sheets script (10000+ rows)

I need help deleting the filtered row in a sheet without timing out.我需要帮助在不超时的情况下删除工作表中的过滤行。 There are over 10,000 rows in the sheet so running a for loop with DeleteRow() is timing out.工作表中有超过 10,000 行,因此使用 DeleteRow() 运行 for 循环超时。

The larger goal of the project is to basically archive data from the main sheet to an archive sheet automatically if the date is more than 31 days ago.该项目的更大目标是,如果日期超过 31 天,则基本上将数据从主工作表自动归档到归档工作表。

This is the current code I currently have to do this but the loop is working really slow with as much data as I have in the sheets.这是我目前必须执行的当前代码,但是循环的工作速度非常慢,数据与工作表中的数据一样多。 If there are any other major performance improvements feel free to make those suggestions as well.如果还有任何其他重大的性能改进,请随时提出这些建议。 This is my first real time working with google app scripts这是我第一次实时使用谷歌应用程序脚本

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var copy_sheet = ss.getSheetByName("upload");
  var paste_sheet = ss.getSheetByName("archive");
  const day = 24 * 60 * 60 * 1000;
  var date = new Date();
  var remove_before_date = new Date()
  remove_before_date.setDate(date.getDate()-31);

  var prev_filter = copy_sheet.getFilter();
  if (prev_filter !== null) {
    prev_filter.remove();
    return;
  }
  //create filter
  var range = copy_sheet.getRange("A:I");

  var filter = range.createFilter();

  var Filter_Criteria = SpreadsheetApp.newFilterCriteria().whenDateBefore(remove_before_date);

  var add_filter = filter.setColumnFilterCriteria(1,Filter_Criteria);

  //copy and paste
  var range = copy_sheet.getDataRange().offset(2,0);
  var last_row_archive = paste_sheet.getDataRange().getNumRows();
  var last_row_upload = copy_sheet.getDataRange().getNumRows();

  paste_sheet.insertRowAfter(last_row_archive)
  range.copyTo(paste_sheet.getRange(last_row_archive+1,1));
  

  //delete from upload
  for (var i = last_row_upload; i > 2; i--) {
    if (!copy_sheet.isRowHiddenByFilter(i)) {
      copy_sheet.deleteRow(i);
    }
}

  //remove filters
  filter.remove();

}```

The execution will be much faster if you如果你,执行会快得多

  • get all values of source sheet获取源表的所有值
  • filter them as you wish根据需要过滤它们
  • split them into two arrays: array to remove, array to stay将它们分成两个数组:要删除的数组,要保留的数组
  • place values of these arrays to source sheet and target sheet respectively.将这些数组的值分别放置到源工作表和目标工作表中。
function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var source = ss.getSheetByName('upload');
  var target = ss.getSheetByName('archive');
  
  var data = source.getDataRange();
  var range = source.getRange(3,1,data.getNumRows()-2, data.getNumColumns());
  
  var values = range.getValues();
  var datesCol = 'I'; //replace this with where your dates are
  var datesColIndex = source.getRange(datesCol + ':' + datesCol).getColumn()-1;
  var lastRowArchive = target.getDataRange().getNumRows();

  //this filters data and gets all rows, the date of which earlier then 31 days.
  var valuesToRemove = values.filter(function(row) {
    var dayInMs= 24 * 60 * 60 * 1000;
    return new Date().valueOf() - new Date(row[datesColIndex]).valueOf() >= dayInMs*31;
  })
  
  //this creates a new array containing only the remaining rows
  var valuesToStay = values.filter(row => !valuesToRemove.includes(row));
  
  //if there are values to remove
  if (valuesToRemove.length) {
    //clear the range in the source sheet
    range.clearContent(); 
    
    //place valuesToStay array to the source sheet
    source.getRange(3,1,valuesToStay.length,valuesToStay[0].length)
    .setValues(valuesToStay);

    //place valuesToRemove array to end of the target sheet
    target.getRange(lastRowArchive+1,1,valuesToRemove.length, valuesToRemove[0].length)
    .setValues(valuesToRemove);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM