跨非连续行批量删除行
Batch row deletions across non-consecutive rows
我正在编写一个脚本来存档(复制和删除)电子表格中的行。
为此,我检查了工作表中的每一行,看它是否已完成。
我可以通过收集所有行并将值的范围全部写在末尾来批处理第一个复制过程。
但是,当需要删除行时,我仍然必须循环并调用sheet.deleteRow()
once for each row. I can't use sheet.deleteRows()
,因为这些行不是连续的。
这是我尝试使用脚本的方式的示例:
function archiveRows_(archiveSheet, sheetID) {
// get req values
var reqSpreadSheet = SpreadsheetApp.openById(sheetID);
var reqSheet = reqSpreadSheet.getSheetByName("Mstr_Wrkbk");
var currentValues = reqSheet.getDataRange().getValues();
// container for staged data
var rowsToArchive = [];
var rowsToDelete = [];
// check for archivable content
var currentRows = currentValues.length;
for (i = 0; i < currentRows - 1; i++) {
var row = currentValues[i]
// check if we meet the criteria for archival
if (shouldArchive_(row)) {
// add row to archive list
rowsToArchive.push(row);
rowsToDelete.push(i + 1);
}
}
// archive rows if we found some
var numRows = rowsToArchive.length; if (!numRows) return 0;
var numCols = rowsToArchive[0].length;
// add rows to archive sheet
var nextFreeRow = archiveSheet.getLastRow();
archiveSheet.insertRows(nextFreeRow + 1, numRows);
// write archive rows
archiveSheet.getRange(nextFreeRow + 1,1, numRows, numCols).setValues(rowsToArchive);
// Committ Changes
SpreadsheetApp.flush();
// delete original rows (we have to loop backwards so delete works)
for (i = rowsToDelete.length - 1; i >= 0; i--) {
// delete row from master sheet
var rowNum = rowsToDelete[i];
reqSheet.deleteRow(rowNum);
}
// Committ Changes
SpreadsheetApp.flush();
return numRows;
}
就是这部分运行的很慢:
// delete original rows (we have to loop backwards so delete works)
for (i = rowsToDelete.length - 1; i >= 0; i--) {
// delete row from master sheet
var rowNum = rowsToDelete[i];
reqSheet.deleteRow(rowNum);
}
有什么方法可以优化/批处理这个操作吗?
如果您只关心值,您可以删除整个 sheet 并粘贴 rowsToArchive:
reqSheet.getDataRange().clear().setValues(rowsToArchive);
如果您关心格式化,您可以像对待值一样对待它们的数组,几乎所有的格式化选项都可以获取和设置,请在 https://developers.google.com/apps-script/reference/spreadsheet/range 中检查它们。
归档行必须有一些标准。您可以使用相同的标准进行排序,然后一次删除所有内容(为此也复制),然后取消排序吗?
我正在编写一个脚本来存档(复制和删除)电子表格中的行。
为此,我检查了工作表中的每一行,看它是否已完成。
我可以通过收集所有行并将值的范围全部写在末尾来批处理第一个复制过程。
但是,当需要删除行时,我仍然必须循环并调用sheet.deleteRow()
once for each row. I can't use sheet.deleteRows()
,因为这些行不是连续的。
这是我尝试使用脚本的方式的示例:
function archiveRows_(archiveSheet, sheetID) {
// get req values
var reqSpreadSheet = SpreadsheetApp.openById(sheetID);
var reqSheet = reqSpreadSheet.getSheetByName("Mstr_Wrkbk");
var currentValues = reqSheet.getDataRange().getValues();
// container for staged data
var rowsToArchive = [];
var rowsToDelete = [];
// check for archivable content
var currentRows = currentValues.length;
for (i = 0; i < currentRows - 1; i++) {
var row = currentValues[i]
// check if we meet the criteria for archival
if (shouldArchive_(row)) {
// add row to archive list
rowsToArchive.push(row);
rowsToDelete.push(i + 1);
}
}
// archive rows if we found some
var numRows = rowsToArchive.length; if (!numRows) return 0;
var numCols = rowsToArchive[0].length;
// add rows to archive sheet
var nextFreeRow = archiveSheet.getLastRow();
archiveSheet.insertRows(nextFreeRow + 1, numRows);
// write archive rows
archiveSheet.getRange(nextFreeRow + 1,1, numRows, numCols).setValues(rowsToArchive);
// Committ Changes
SpreadsheetApp.flush();
// delete original rows (we have to loop backwards so delete works)
for (i = rowsToDelete.length - 1; i >= 0; i--) {
// delete row from master sheet
var rowNum = rowsToDelete[i];
reqSheet.deleteRow(rowNum);
}
// Committ Changes
SpreadsheetApp.flush();
return numRows;
}
就是这部分运行的很慢:
// delete original rows (we have to loop backwards so delete works)
for (i = rowsToDelete.length - 1; i >= 0; i--) {
// delete row from master sheet
var rowNum = rowsToDelete[i];
reqSheet.deleteRow(rowNum);
}
有什么方法可以优化/批处理这个操作吗?
如果您只关心值,您可以删除整个 sheet 并粘贴 rowsToArchive:
reqSheet.getDataRange().clear().setValues(rowsToArchive);
如果您关心格式化,您可以像对待值一样对待它们的数组,几乎所有的格式化选项都可以获取和设置,请在 https://developers.google.com/apps-script/reference/spreadsheet/range 中检查它们。
归档行必须有一些标准。您可以使用相同的标准进行排序,然后一次删除所有内容(为此也复制),然后取消排序吗?