Я пытаюсь создать макрос, чтобы стереть все строки с пустыми значениями в столбце D. Первоначально я использовал этот код, который нашел:
function deleteRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Datos Competidor 2 - EV');
var r = s.getRange('D:D');
var v = r.getValues();
for(var i=v.length-1;i>=0;i--)
if (v[0,i]=='')
s.deleteRow(i+1);
};
Однако чрезмерное количество вызовов API сделало это очень медленным, а иногда даже терпело неудачу из-за тайм-аута.
Я решил просто добавить все строки, соответствующие условию, в список, а затем просто передать его в deleteRow(), чтобы вызывать API только один раз, используя этот код:
function deleteBlankRows() {
emptyRange=[]
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Datos Competidor 2 - EV');
var r = s.getRange('D:D');
var v = r.getValues();
for(var i=v.length-1;i>=0;i--)
if (v[0,i]=='')
emptyRange.push((i)+":"+(i));
ss.getRangeList(emptyRange).activate();
ss.getActiveSheet().deleteRows(ss.getActiveRange().getRow(), ss.getActiveRange().getNumRows());
};
Выполнение, кажется, работает нормально, завершаясь за 1-2 секунды, однако строки не стираются так сильно, как выбираются к концу выполнения.
Вот что я вижу:
Есть идеи, почему это происходит?
Спасибо!





Я считаю, что ваша цель заключается в следующем.
Как в этом случае использовать Sheets API? Когда используется Sheets API, я подумал, что стоимость процесса удаления строк может быть немного снижена. Когда API листов отражен в вашем скрипте, он становится следующим.
Прежде чем использовать этот скрипт, пожалуйста, включите Sheets API в расширенных службах Google.
function deleteRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Datos Competidor 2 - EV');
var values = s.getRange('D1:D' + s.getLastRow()).getDisplayValues();
var sheetId = s.getSheetId();
var requests = values.reduce((ar, [d], i) => {
if (!d) ar.push({ deleteDimension: { range: { sheetId, startIndex: i, endIndex: i + 1, dimension: "ROWS" } } });
return ar;
}, []).reverse();
Sheets.Spreadsheets.batchUpdate({ requests }, ss.getId());
}
function deleteBlankRows() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const s = ss.getSheetByName('Datos Competidor 2 - EV');
const r = s.getRange('D1:D' + s.getLastRow());
const v = r.getValues().flat();
let d = 0;
v.forEach((e, i) => {
if (!e) {
s.deleteRow(i + 1 - d++)
}
})
}
Спасибо за ответ, Купер, это работает. Однако с точки зрения времени выполнения он такой же, как и первый код, который я опубликовал, поскольку он вызывает API для каждого экземпляра пустой ячейки по отдельности. Я пытаюсь понять, почему второй код, который я опубликовал, не работает, учитывая, что листы прекрасно интерпретируют диапазон. Это просто шаг стирания, который не работает.
Большое спасибо Танайке! Мне придется немного взглянуть на код, чтобы понять, что он на самом деле делает, но это намного быстрее.