Ускорение функции добавления строки - PullRequest
1 голос
/ 26 мая 2020

У меня есть следующий скрипт Google Apps «Добавить строку», который срабатывает, когда пользователь нажимает кнопку:

//Add Row to Additional Duties Sheet
function AddRowtoAdditionalDutiesSheet() {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('3:3').activate();
  spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getActiveRange().getRow(), 1);
  spreadsheet.getActiveRange().offset(0, 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
  spreadsheet.getRange('A4:X4').activate();
  spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('A3:X4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getRange('3:3').activate();
  spreadsheet.getActiveRangeList().clear({contentsOnly: true, commentsOnly: true, skipFilteredRows: true});
  spreadsheet.getRange('G4:K4').activate();
  spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('G3:K4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getRange('F4').activate();
  spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('F3:F4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getRange('R4').activate();
  spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('R3:R4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getRange('X4').activate();
  spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('X3:X4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getRange('A3').activate();
}

Это копия моего листа со столбцами от A до X.

Sample Sheet

Сценарий копирует формулы в определенных ячейках из строки 4 в строку 3 после того, как строка была вставлена. Проблема в том, что много пользователей заполняют лист, и иногда формула не вставляется в строку 3. После долгих наблюдений я считаю, что это потому, что 2 разных пользователя нажимают кнопку одновременно, и сценарий слишком медленно вставить формулу. Есть ли лучший способ написать сценарий, чтобы он работал быстрее?

1 Ответ

3 голосов
/ 26 мая 2020

Как насчет этого ответа?

Пункты модификации:

  • Чтобы снизить стоимость процесса скрипта, я заменил getActiveRange() на диапазон.
  • Для непрерывной работы скрипта я установил LockService.
    • Таким образом, когда кнопку нажимают несколько пользователей, сценарий блокируется, и каждый сценарий, выполняемый каждым пользователем, может быть запущен с эксклюзивной обработкой.

Измененный скрипт:

function AddRowtoAdditionalDutiesSheet() {
  var lock = LockService.getDocumentLock();
  if (lock.tryLock(10000)) {
    try {

      // your script
      var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getActiveSheet().insertRowsBefore(spreadsheet.getRange('3:3').getRow(), 1);
      spreadsheet.getRange('3:3').offset(0, 0, 1, spreadsheet.getActiveRange().getNumColumns()).activate();
      spreadsheet.getRange('A4:X4').autoFill(spreadsheet.getRange('A3:X4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
      spreadsheet.getRange('3:3').clear({contentsOnly: true, commentsOnly: true, skipFilteredRows: true});
      spreadsheet.getRange('G4:K4').autoFill(spreadsheet.getRange('G3:K4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
      spreadsheet.getRange('F4').autoFill(spreadsheet.getRange('F3:F4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
      spreadsheet.getRange('R4').autoFill(spreadsheet.getRange('R3:R4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
      spreadsheet.getRange('X4').autoFill(spreadsheet.getRange('X3:X4'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
      spreadsheet.getRange('A3').activate();

    } catch(e) {
      throw new Error(e);
    } finally {
      lock.releaseLock();
    }
  }
}

Примечание:

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

Ссылка:

...