Непоследовательные результаты в макросах Google Sheets? - PullRequest
2 голосов
/ 27 октября 2019

У меня есть следующая электронная таблица (и это идеальное начальное состояние):

enter image description here

Когда вы вводите число в желтом поле (B55), C55 и D55 рассчитываются (на основе других данных, не относящихся к проблеме).

Вот что мне нужно сделать для макроса: (1) Скопируйте B58 и вставьте значение ("1") вB55. Это изменит значения C55 и D55. (2) Скопируйте C55, вставьте значение в C58. (3) Скопируйте D55, вставьте значение в D58. (4) Повторите шаги 1-4, но на этот раз со строкой 59. (5) Повторите, но со строкой 60. (6) И т. Д.

Так что, если скрипт выполнялся только один раз (на B58), ондолжен выглядеть как ...

enter image description here

Если скрипт выполняется с 4 строками данных года (B58-B61), и это то, что код скриптаниже следует сделать, вывод должен выглядеть следующим образом:

enter image description here

Действительно, он должен работать в течение 20 итераций с конечным значением «100» лет. Но для краткости и для иллюстрации проблемы я остановился на «15». Но скажем, например, я ввожу 100 в желтом поле, я получаю ...

enter image description here

Если бы я запустил сценарий в этот моментоднако я получаю ...

enter image description here

Видите, как они все имеют одинаковое значение? Записанный мной макрос копирует последнюю запись в C55 и D55 вместо вычисленных значений для 1, 5, 10 и т. Д.

Что я делаю не так?

ВотСценарий, который он создал:


function TEST1() {
  var spreadsheet = SpreadsheetApp.getActive();

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B58').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('C58').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D58').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B59').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('C59').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D59').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B60').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('C60').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D60').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B61').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('C61').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D61').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};

Примечание: это упрощение большего требования. Необходим макрос, я не могу превратить таблицу в несколько формул.

1 Ответ

1 голос
/ 27 октября 2019
  • Вы хотите скопировать B58 в B55. В это время вычисляются C55 и D55. Вы хотите скопировать вычисленные значения от C55:D55 до C58:D58.
    • Вы хотите запустить этот поток для каждой строки.
  • Вы хотите добиться этого, изменив свой скрипт.

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

Точка модификации:

  • В вашем случае, чтобы рассчитать значения, используйте SpreadsheetApp.flush(). После запуска SpreadsheetApp.flush() вычисленные значения копируются.

Шаблон 1:

В этом шаблоне ваш скрипт изменяется. Пожалуйста, измените следующим образом.

Модифицированный скрипт:

function TEST1() {
  var spreadsheet = SpreadsheetApp.getActive();

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B58').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  SpreadsheetApp.flush(); // Added
  spreadsheet.getRange('C58').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D58').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B59').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  SpreadsheetApp.flush(); // Added
  spreadsheet.getRange('C59').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D59').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B60').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  SpreadsheetApp.flush(); // Added
  spreadsheet.getRange('C60').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D60').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  spreadsheet.getRange('B55').activate();
  spreadsheet.getRange('B61').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  SpreadsheetApp.flush(); // Added
  spreadsheet.getRange('C61').activate();
  spreadsheet.getRange('C55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  spreadsheet.getRange('D61').activate();
  spreadsheet.getRange('D55').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};

Шаблон 2:

В этом шаблоне объявляются стартовая строка и конечная строка, которую вы хотите получить, изначения копируются в цикл for. Пожалуйста, измените следующим образом.

Модифицированный скрипт:

function TEST1() {
  var startRow = 58; // Please set the start row. In this case, it's row 58.
  var endRow = 61; // Please set the start row. In this case, it's row 61.

  var spreadsheet = SpreadsheetApp.getActive();
  for (var row = startRow; row <= endRow; row++) {
    spreadsheet.getRange("B" + row).copyTo(spreadsheet.getRange("B55"), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
    SpreadsheetApp.flush();
    spreadsheet.getRange("C55:D55").copyTo(spreadsheet.getRange("C" + row + ":D" + row), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
  }
}

Ссылка:

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