Код скрипта Google Apps для удаления строк на основе частичных данных ячейки - PullRequest
0 голосов
/ 08 февраля 2020

Я пытаюсь удалить строки на основе частичных данных ячейки, содержащихся в ячейках столбца А. Например, ячейка может содержать значение «OX USPEA», номер детали цилиндра, я работаю в газовой промышленности и хочу удалить любую строку, содержащую это значение. Я работаю с почти 200 строками из примерно 500, которые содержат начальный текст "OX USPE", но заканчиваются различными текстовыми комбинациями. Это фрагмент кода, который я разработал до сих пор, но я не могу заставить его работать. Я получаю сообщение об ошибке «Исключение: эти строки выходят за границы. (Строка 218, файл« макросы »)», строка 218 - это место, где возникает ошибка, поскольку у меня есть много других строк кода в этом же документе, вот код, который я я фокусируюсь на:

function test() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Fast Fill'), true);
  var snipLoop = spreadsheet.getRange("A:A").getValues();
  for(var i = 0; i<snipLoop.length; i++){
    if(snipLoop.indexOf("ox uspe")){

      spreadsheet.deleteRow(i);

    }
  }

};

Опять же, когда я запускаю это, я получаю ошибку «Исключение: эти строки выходят за пределы. (строка 218, файл« макросы »)». Что я делаю неправильно?

Редактировать:

На основании ввода для пользователя ADW я обновил свой код до следующего:

function test() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Fast Fill'), true);
  var snipLoop = spreadsheet.getRange("A:A").getValues();
  for(var i = (snipLoop.length - 1); i >= 0; i--){
    if(snipLoop.indexOf("OX USPE") > -1){

      spreadsheet.deleteRow(i);

    }
  }

};

Мне необходимо дополнительно объяснить, что строки, которые я собираюсь удалить храните значения данных в столбцах от A до E, если это имеет значение.

Когда я запускаю этот код, я не получаю ошибок, и код выполняется полностью, однако с активированным листом ничего не происходит. Здесь я скопировал и вставил имя листа, Fast Fill, так что я уверен в его точности в коде. Кто-нибудь может объяснить это?

Редактировать: вот упрощенная электронная таблица, аналогичная той, с которой я работаю

Material    Req
CD 50S      21
CD FG20A    49
CD USP50    25

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

Вот несколько вещей, которые вы можете рассмотреть:

  1. Если ячейка не содержит "ox uspe", snipLoop.indexOf("ox uspe") даст значение -1. Чтобы остановить оператор if от удаления этой строки, вам может потребоваться изменить оператор на

    if(snipLoop[i].indexOf("ox uspe") > -1){ [отредактировано]


При удалении строк лучше всего начинать снизу.

Это связано со следующей проблемой удаления сверху: скажем, необходимо удалить обе строки 10 и 11. После удаления строки 10 строка 11 становится строкой 10. Сценарий считывает данные из массива, выбранного до удаления строки 10. Таким образом, требуется, чтобы строка 11 тоже была удалена. Но на этом этапе все строки переместились на одну, так как строка 10 была удалена. Поэтому вместо строки 11 строка 12 удаляется.

Я бы предложил следующее:

for (var i = (snipLoop.length - 1); i >= 0; i--){

0 голосов
/ 10 февраля 2020

Если я вас правильно понял, вы хотите удалить строки, в которых ячейка в столбце A содержит "OX USPE". Если это так, вы можете сделать это:

function test() {
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getSheetByName('Fast Fill');
  var textToFind = "OX USPE";
  var firstRow = 1;
  var column = 1;
  var numRows = sheet.getLastRow() - firstRow + 1;
  var snipLoop = sheet.getRange(firstRow, column, numRows).getValues().map(function(row) {
    return row[0];
  });
  for(var i = snipLoop.length - 1; i >= 0; i--){
    if(snipLoop[i].indexOf(textToFind) === 0){
      sheet.deleteRow(i + firstRow);
    }
  }
};

Основная проблема в вашем коде состоит в том, что getValues ​​ возвращает двумерный массив. При использовании Array.prototype.indexOf () до snipLoop вы ищете элемент во внешнем массиве, который соответствует строке OX USPE. Поскольку каждый элемент во внешнем массиве фактически является другим массивом (внутренним массивом), это не может работать. Он не удалит ни одной строки.

Чтобы проверить, содержит ли значение ячейки какую-либо строку, вместо этого следует использовать String.prototype.indexOf () для каждого значения во внутреннем массиве. Чтобы сделать это, вы можете (1) сначала использовать map для преобразования 2D-массива в одномерный массив (вы можете сделать это, потому что вы получаете только столбец A, поэтому каждый элемент во внешнем массиве содержит только внутренний массив только с одним значением, и (2) примените индекс i к результирующему одномерному массиву.

Также может возникнуть проблема с индексом удаляемых строк. Индексы массивов начинаются с 0 (snipLoop), но индексы строк начинаются с 0. Из-за этого вы должны сделать это вместо этого: sheet.deleteRow(i + firstRow);

Наконец, я немного изменил ваш диапазон, так что диапазон задается указанием firstRow, column и number of rows (см. getRange (строка, столбец, numRows) ) вместо использования записи A1. Таким образом, скрипт будет перебирайте только строки с содержимым, и легче изменить диапазон для извлечения. Я также удалил часть setActiveSheet, потому что нет необходимости использовать этот метод. Вы можете просто получить нужный лист по имени.

* 10 31 * Ссылка:
...