Поскольку вы не хотите удалять строки, просто clear()
их, и они все находятся на одной вкладке рабочего листа, это отличный вариант использования для RangeList
s , которыйпозволяют применять конкретные Range
методы к несмежным Range
с.В настоящее время единственный способ создать RangeList
состоит из массива ссылочных обозначений (т. Е. RangeList
отличается от массива Range
объектов ), поэтомупервая цель, которую мы имеем, - это префикс нашего массива данных листа JavaScript для проверки с помощью используемой строки ссылки.Мы могли бы написать функцию для преобразования индексов массива из 0-базовых целых чисел в нотацию A1, но ссылка на R1C1 вполне допустима для передачи конструктору RangeList
, поэтому нам просто нужно учитывать строки заголовка и 0-base против 1-базовая разница в индексировании.
Стратегия заключается в следующем:
- Пакетное чтение данных листа в JavaScript
Array
- Пометить каждый элемент массива(т. е. каждая строка) со строкой R1C1, которая идентифицирует местоположение, откуда поступил этот элемент.
Filter
массив данных листа на основе содержимого каждого элемента - Хранить элементы там, где каждый элемент-элемент (значения столбца в этой строке) преобразуется в логическое значение (т. е. не имеет того же значения, что и пустая ячейка)
- Передать метки каждой из сохраненных строк в
RangeList
конструктор - Используйте
RangeList
методы в RangeList
Поскольку этот подход использует только 3 вызова электронных таблиц (помимо начальной настройки дляпакетное чтение), против 1 рЧтобы очистить строку, она должна быть значительно быстрее.
function clearFullyFilledRows() {
// Helper function that counts the number of populated elements of the input array.
function _countValues(row) {
return row.reduce(function (acc, val) {
var hasValue = !!(val || val === false || val === 0); // Coerce to boolean
return acc + hasValue; // true == 1, false == 0
}, 0);
}
const sheet = SpreadsheetApp.getActiveSheet();
const numHeaderRows = 1,
numRows = sheet.getLastRow() - numHeaderRows;
const startCol = 1,
numCols = sheet.getLastColumn();
// Read all non-header sheet values into a JavaScript array.
const values = sheet.getSheetValues(1 + numHeaderRows, startCol, numRows, numCols);
// From these values, return a new array where each row is the origin
// label and the count of elements in the original row with values.
const labeledCounts = values.map(function(row, index) {
var rNc = "R" + (numHeaderRows + 1 + index) + "C";
return [
rNc + startCol + ":" + rNc + (startCol + numCols - 1),
_countValues(row)
];
});
// Filter out any row that is missing a value.
const toClear = labeledCounts.filter(function (row) { return row[1] === numCols; });
// Create a RangeList from the first index of each row (the R1C1 label):
const rangeList = sheet.getRangeList(toClear.map(function (row) { return row[0]; }));
// Clear them all:
rangeList.clear();
}
Обратите внимание, что из-за того, что эти очищенные строки могут быть непересекающимися, ваш результирующий лист может быть завален строками с данными и строками без данных.Вызов sheet.sort(1)
будет сортировать все не замороженные строки на листе, перемещая недавно пустые строки вниз (да, вы можете программно установить замороженные строки).В зависимости от того, как на этот лист ссылаются в других местах, это может быть нежелательно.
Дополнительные ссылки: