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

时间:2021-07-26 04:35:16

标签: google-apps-script optimization timeout delete-row

我需要帮助在不超时的情况下删除工作表中的过滤行。工作表中有超过 10,000 行,因此使用 DeleteRow() 运行 for 循环超时。

该项目的更大目标是,如果日期超过 31 天,基本上将数据从主工作表自动归档到归档工作表。

这是我目前必须执行此操作的当前代码,但是循环的工作速度非常慢,数据与工作表中的数据一样多。如果还有任何其他重大的性能改进,请随时提出这些建议。这是我第一次实时使用谷歌应用程序脚本

  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();

}```

1 个答案:

答案 0 :(得分:2)

执行会更快

  • 获取源表的所有值
  • 根据需要过滤它们
  • 将它们分成两个数组:要删除的数组,要保留的数组
  • 将这些数组的值分别放置到源工作表和目标工作表中。
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);
  }
}
相关问题