我需要帮助在不超时的情况下删除工作表中的过滤行。工作表中有超过 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();
}```
答案 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);
}
}