#javascript #google-apps-script #google-sheets
Вопрос:
У меня есть лист, на котором внизу записываются новые строки с новыми значениями каждый час или около того. Иногда вызов API вызывает некоторую ошибку. Я изменил сообщение об ошибке для loading…
, но я все равно хотел бы, чтобы был способ отфильтровать эти ошибки из столбцов и заменить эти значения значениями, взятыми из ячейки чуть выше, если в этой нет ошибки.
Итак, это пример ячеек с ошибками:
Вот как выглядит массив, полученный с помощью кода, который я использовал ниже:
Я начал с этого:
function deleteErrors () {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CELL_ERRORS");
let checkRange = sheet.getRange(1, 1, sheet.getLastRow(), 2).getDisplayValues();
let rangeReversed = checkRange.reverse();
console.log(rangeReversed);
}
Как я могу удалить "Loading…"
и заменить его значением ячейки чуть выше, если в ячейке выше нет ошибки, или в случае массива массивов со значением ниже, так как я использовал обратный. Я использовал обратный, потому что идея состоит в том, чтобы фильтровать снизу, когда строки записываются снизу.
Итак, вот как это должно выглядеть после применения правильного сценария:
И массив массивов должен выглядеть так:
Но я думаю, что этот массив массивов не так уж важен. В принципе, мне просто нужно, чтобы ячейки с Loading…
ошибкой были перезаписаны значением ячейки чуть выше, если эта ячейка выше тоже Loading…
, конечно, отсутствует.
Возможно ли это? Возможно, для этого есть какой-то способ использовать формулу, но я предпочитаю использовать сценарий приложений.
Я попробовал что-то вроде этого:
function deleteErrors () {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CELL_ERRORS");
let checkRange = sheet.getRange(1, 1, sheet.getLastRow(), 2).getDisplayValues();
let rangeReversed = checkRange.reverse();
console.log(rangeReversed);
// Get row numbers of cells on col 1 with errors
let cellsCol1 = sheet.getRange(1, 1, sheet.getLastRow(), 1).createTextFinder("Loading…").findAll().map(x => x.getRowIndex());
console.log(cellsCol1);
// Get row numbers of cells on col 1 above the ones with error (hopefully these won't have errors!)
let okCellsCol1 = cellsCol1.map(x => x - 1);
console.log(okCellsCol1);
// Get row numbers of cells on col 2 with errors
let cellsCol2 = sheet.getRange(1, 2, sheet.getLastRow(), 2).createTextFinder("Loading…").findAll().map(x => x.getRowIndex());
console.log(cellsCol2);
// Get row numbers of cells on col 2 above the ones with error (hopefully these won't have errors!)
let okCellsCol2 = cellsCol2.map(x => x - 1);
console.log(okCellsCol2);
}
Это не работает, но как я могу уйти отсюда?
Мое досье: https://docs.google.com/spreadsheets/d/1ExXtmQ8nyuV1o_UtabVJ-TifIbORItFMWjtN6ZlruWc/edit?usp=sharing
Комментарии:
1. «Итак, вот пример:» является ли ситуация ввода образца? Если я правильно понимаю, можете ли вы предоставить пример выходной ситуации, которую вы ожидаете, в виде изображения?
2. Хорошо, я просто отредактировал вопрос. Я надеюсь, что это более ясно.
3. Благодарим вас за ответ и предоставление примера ситуации с выводом. Из вашего обновленного вопроса я предложил ответ. Не могли бы вы, пожалуйста, подтвердить это? Если это было бесполезно, я приношу свои извинения.
Ответ №1:
- Вы хотите добиться следующей ситуации. (Эти изображения взяты из вопроса ОП.)
- От
- Для
- От
В этом случае, как насчет следующего измененного сценария?
Измененный сценарий:
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CELL_ERRORS");
let checkRange = sheet.getRange(1, 1, sheet.getLastRow(), 2).getDisplayValues();
// I modified below script.
const values = checkRange.map(([a, b], i, ar) => {
if (i > 0) {
return [a == "Loading…" ? ar[i - 1][0] : a, b == "Loading…" ? ar[i - 1][1] : b];
}
return [a, b];
});
console.log(values)
Примечание:
- В этом измененном скрипте используется, когда 1-я строка включает
Loading…
Loading…
. Если вы хотите заменить это другими, пожалуйста, скажите мне.
Ссылка:
Добавлен:
О How can we overwrite the values back onto the cells?
и How can we overwrite the values back onto the cells? Also in my main file I have 21 columns. This will work for 2 columns. If I add the 3rd it won't do the same for the 3rd column in the array. Finally if 2 cells in a row have error (one on top of the other), the Loading… won't disappear.
в комментарии я обновил приведенный выше сценарий следующим образом.
Измененный сценарий:
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CELL_ERRORS");
let checkRange = sheet.getRange(1, 1, sheet.getLastRow(), 3);
const currentValues = checkRange.getDisplayValues();
const transposed = currentValues[0].map((_, c) => currentValues.map(r => r[c]));
const transposedValues = transposed.map(row => {
let temp = "";
return row.map((e, i) => {
if (i > 0) {
if (e == "Loading…") {
return temp;
} else {
temp = e;
}
} else {
temp = e;
}
return e;
});
});
const values = transposedValues[0].map((_, c) => transposedValues.map(r => r[c]));
console.log(values)
checkRange.setValues(values);
- В этой модификации, я думаю, что ваши дополнительные ситуации могут быть заполнены.
Комментарии:
1. @Verminous Из
About
Него работает на массиве.`, Я рад. Что касается ваших дополнительных ситуаций, я добавил в свой ответ еще один измененный сценарий. Не могли бы вы, пожалуйста, подтвердить это? Если это был не тот результат, которого вы ожидали, я приношу свои извинения.2. @Verminous Спасибо, что ответили. Я должен извиниться за свое плохое знание английского языка. К сожалению, я не могу понять вашу текущую проблему с вашим дополнительным вопросом
(1,1)
,(100, 2)
checkRange = sheet.getRange(100, 2, sheet.getLastRow(), sheet.getLastColumn());
который не используется в моем измененном сценарии и в вашем сценарии. Итак, можете ли вы предоставить подробную информацию об этом? Под этим я хотел бы попытаться понять это.3. @Verminous Спасибо, что ответили. О
sheet.getRange(6500, 2, sheet.getLastRow(), 3);
, в данном случае,sheet.getLastRow()
это все строки данных. В этом случае строки извлекаются от 6500 до 6500sheet.getLastRow()
. Если вы хотите получить строки данных от 6500 до последней строки, как насчет того, чтобы изменить их наsheet.getRange(6500, 2, sheet.getLastRow() - 6499, 3);
? Но если я неправильно понял ваш дополнительный вопрос, я еще раз приношу свои извинения.4. @Verminous Кстати, в этом случае, пожалуйста, будьте осторожны с номером столбца.
sheet.getRange(6500, 2, sheet.getLastRow() - 6499, 3);
извлекает столбцы B, C и D.5. @Verminous А также, о
let checkRange = sheet.getRange(2, 2, sheet.getLastRow(), 3);
, в данном случае, как насчетlet checkRange = sheet.getRange(2, 2, sheet.getLastRow() - 1, 3);
?