Ускорьте изменения от сценария к разбросанным ячейкам в листах Google - PullRequest
0 голосов
/ 19 марта 2019

У меня есть лист, который показывает результаты расчетов на основе других листов поддержки.Изменения вносятся вручную, но «сводный» лист - это только формулы.Эти изменения появляются в разбросанных ячейках, по большей части несмежных.

Я хочу выделить, какие ячейки изменились в сводном листе после ручного изменения на вспомогательных листах.Для этого я использую второй сводный лист, который начинается с копии основного.

Последний компонент - это скрипт, который запускается после редактирования.Он просматривает итоговый диапазон и сравнивает значения со второй копией.Любые различия выделяются в основном резюме и копируются во второе резюме.

Этот процесс работает, но довольно медленный, я думаю из-за обновлений.Псевдокод:

var src = summary.getRange(...)
var dst = copy.getRange(...)

var src_cell;
var dst_cell;

src.setBackground('white'); // Bulk reset of changes

for (row = 1; row < src.getNumRows(); row++) {
    for (col = 1; col < src.getNumColumns(); col++) {
        src_cell = src.getCell(row, col);
        dst_cell = src.getCell(row, col);

        if (src_cell.getDisplayValue() != dst_cell.getDisplayValue()) {
            dst_cell.setValue(src_cell.getDisplayValue());
            src_cell.setBackground('gray');
        }
    }
}

Я думаю, что нет способа массового обновления разбросанных диапазонов, что кажется простым решением.

Я ищу способы ускорить этот процесс,либо в сценарии, либо с помощью другой стратегии.

1 Ответ

1 голос
/ 19 марта 2019

В соответствии с официальными «рекомендациями» вы должны читать данные связанных ячеек, а не многократно читать и, возможно, записывать значения.Это утверждение предполагает, что установки значений в dst не влияют на значения для будущих чтений.

Таким образом, самое простое изменение заключается в использовании Range#getDisplayValues для src и dst:

...
src.setBackground("white");
var srcValues = src.getDisplayValues();
var dstValues = dst.getDisplayValues();

srcValues.forEach(function (srcRow, r) {
  var dstRow = dstValues[r];
  srcRow.forEach(function (value, c) {
    if (value !== dstRow[c]) {
      dst.getCell(r + 1, c + 1).setValue(value);
      src.getCell(r + 1, c + 1).setBackground("gray");
    }
  });
});

Дополнительная оптимизация заключается в использовании класса RangeList для пакетной обработки изменений.Чтобы создать RangeList, вам нужен массив обозначений ячеек / диапазонов, которые могут использовать адресацию в стиле R1C1 или A1.R1C1 проще всего вычислить.

...
var dstChanges = [];
var srcChanges = [];
...

    if (value !== dstRow[c]) {
      dstChanges.push({row: r + 1, col: c + 1, newValue: value});
      srcChanges.push({row: r + 1, col: c + 1});
    }
...

if (srcChanges.length > 0) {
  var srcRow = src.getRow();
  var dstRow = dst.getRow();
  var srcCol = src.getColumn();
  var dstCol = dst.getColumn();
  copy.getRangeList(dstChanges.map(function (obj) {
    return "R" + (obj.row + dstRow) + "C" + (obj.col + dstCol);
  }).getRanges().forEach(function (rg, i) {
    rg.setValue(dstChanges[i].newValue);
  });
  summary.getRangeList(srcChanges.map(function (obj) {
    return "R" + (obj.row + srcRow) + "C" + (obj.col + srcCol);
  }).setBackground("gray");
}
...

Другие ссылки

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