Как наиболее эффективно очистить строку, если ВСЕ ячейки имеют значение с помощью скрипта Apps? - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь найти функцию, которая будет очищать содержимое (не удалять строку), если все ячейки в диапазоне имеют значения.Приведенный ниже сценарий не работает должным образом, и я был бы очень признателен за любую помощь / совет, который у вас есть.В настоящее время он очищает только одну строку и не выполняет итерацию по всему набору данных.Я думал о том, чтобы перебрать строки и проверить каждую ячейку в отдельности.Если каждая из переменных имеет значение, очистите этот диапазон и перейдите к следующей строке.

Вот ссылка на образец Google Sheet с данными и сценарием в Редакторе сценариев.

function MassRDDChange() {
       // Google Sheet Record Details
       var ss = SpreadsheetApp.openById('1bcrEZo3IkXiKeyD47C_k2LIRy9N9M6SI2h2MGK1Cj-w');
       var dataSheet = ss.getSheetByName('Data Entry');

       // Initial Sheet Values
       var newLastColumn = dataSheet.getLastColumn();
       var newLastRow = dataSheet.getLastRow();
       var dataToProcess = dataSheet.getRange(2, 1, newLastRow, newLastColumn).getValues().filter(function(row) {
           return row[0]
       }).sort();
       var dLen = dataToProcess.length;

       // Clear intiial sheet
       for (var i = 0; i < dLen; ++i) {
           var row = 2;
           var orderNumber = dataToProcess[i][0].toString();
           var rdd = dataToProcess[i][1].toString();
           var submittedBy = dataToProcess[i][2].toString();
           var submittedOn = dataToProcess[i][3].toString();
           if (orderNumber && rdd && submittedBy && submittedOn) {
               dataSheet.getRange(row, 1, 1, newLastColumn).clear();
               row++;
           } else {
               row++; // Go to the next row
               continue;
           }
       }
   }

Спасибо!

1 Ответ

0 голосов
/ 07 июня 2018

Поскольку вы не хотите удалять строки, просто clear() их, и они все находятся на одной вкладке рабочего листа, это отличный вариант использования для RangeList s , которыйпозволяют применять конкретные Range методы к несмежным Range с.В настоящее время единственный способ создать RangeList состоит из массива ссылочных обозначений (т. Е. RangeList отличается от массива Range объектов ), поэтомупервая цель, которую мы имеем, - это префикс нашего массива данных листа JavaScript для проверки с помощью используемой строки ссылки.Мы могли бы написать функцию для преобразования индексов массива из 0-базовых целых чисел в нотацию A1, но ссылка на R1C1 вполне допустима для передачи конструктору RangeList, поэтому нам просто нужно учитывать строки заголовка и 0-base против 1-базовая разница в индексировании.

Стратегия заключается в следующем:

  1. Пакетное чтение данных листа в JavaScript Array
  2. Пометить каждый элемент массива(т. е. каждая строка) со строкой R1C1, которая идентифицирует местоположение, откуда поступил этот элемент.
  3. Filter массив данных листа на основе содержимого каждого элемента
    • Хранить элементы там, где каждый элемент-элемент (значения столбца в этой строке) преобразуется в логическое значение (т. е. не имеет того же значения, что и пустая ячейка)
  4. Передать метки каждой из сохраненных строк вRangeList конструктор
  5. Используйте 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) будет сортировать все не замороженные строки на листе, перемещая недавно пустые строки вниз (да, вы можете программно установить замороженные строки).В зависимости от того, как на этот лист ссылаются в других местах, это может быть нежелательно.

Дополнительные ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...