Повышение эффективности загрузки кода App Script в Google Sheets - PullRequest
1 голос
/ 05 февраля 2020

ВЫПУСК

У меня есть электронная таблица, в которой я генерирую конечный столбец на основе других имеющихся столбцов. Я делаю это, используя код скрипта приложения ниже. Сейчас в этой таблице 1147 строк, и я часто замечаю длительный период загрузки для извлечения всех строк.

Есть ли какие-либо предложения о том, как я могу улучшить эффективность и оперативность?

ПРИМЕР

enter image description here

ФОРМУЛА Массива на конечной колонне

=ARRAYFORMULA(
IF(A2:A="Spec", "# SPEC "&B2:B, 
IF(A2:A="Scenario", "## "&B2:B, 
IF(A2:A="Step", "* "&TAGS(C2:C,D2:D), 
IF(A2:A="Tag", "Tags: "&REGEXREPLACE(B2:B,"\s",""), 
IF(A2A="", ""))))))

КОД СКРИПТА APP

Utilities.sleep(3000)
/** @OnlyCurrentDoc */

function TAGS(input,textreplacement) {
  if (input.length > 0) {
    var lst = input.split(",")
    var rep = textreplacement.match(/<[^>]*>/g)
    for (i in rep){
      textreplacement = textreplacement.replace(rep[i],'"'+lst[i]+'"')
    }
    return textreplacement
  }
  else{
    return textreplacement
  }
}

РЕДАКТИРОВАТЬ

Из рисунка ниже я хотел бы заменить все на треугольные скобки <> в столбце D, со значениями в столбце C, разделенными запятой.

Я использую формулу массива в столбце E для первоначального преобразования, а затем использую функцию TAGS для добавления значений.

В идеале я бы использовал формулу массива в одной ячейке вверху столбца E, чтобы выполнить все замены.

enter image description here

Ответы [ 2 ]

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

Пользовательские функции в скрипте Google Apps, как правило, занимают много времени, и я бы не рекомендовал использовать их в нескольких ячейках. Я хотел бы лучше понять, что вы пытаетесь сделать с этими данными, чтобы ответить правильно, но в любом случае, я бы попробовал одно из следующих двух решений:

1 - Встроенная формула:

Использование только собственных функций обеспечивает лучшую производительность. Не уверен, как вы могли бы достичь этого, так как вы выполняете итерации внутри этой функции TAGS.

2 - Рассчитать значения поочередно со скриптом и заменить значения в столбце E:

Вы можете создать функцию, которая может запускаться из события onEdit или Активируется пользовательским меню . Обычно это будет выглядеть так:

function calculateColumnE() {
  var sheet = SpreadsheetApp.openById('some-id').getSheetByName('some-name');
  var row_count = sheet.getLastRow();
  var input_data = sheet.getRange(1, 1, row_count, 4).getValues();
  var data = [];
  for (var i = 0; i < row_count; i++) {
      var row_data; // this variable will receive value for column E in this row
      /*
      ...
      manage input_data here
      ...
      */
      data.push([row_data]); // data array MUST be a 2 dimensional array
  }

  sheet.getRange(1, 5, data.length, 1).setValues(data);
}

РЕДАКТИРОВАТЬ

Вот полный код для решения 2:

function TAGS(input,textreplacement) { //keeping your original function
  if (input.length > 0) {
    var lst = input.split(",")
    var rep = textreplacement.match(/<[^>]*>/g)
    for (i in rep){
      textreplacement = textreplacement.replace(rep[i],'"'+lst[i]+'"')
    }
    return textreplacement
  }
  else{
    return textreplacement
  }
}

function calculateColumnE() {
  var sheet = SpreadsheetApp.openById('some-id').getSheetByName('some-name');
  var row_count = sheet.getLastRow();
  var input_data = sheet.getRange(1, 1, row_count, 4).getValues();
  var data = [];
  for (var i = 0; i < row_count; i++) {
      var row_data; // this variable will receive value for column E in this row
      if (input_data[i][0] == "Spec") {
        row_data = "# SPEC " + input_data[i][1];
      } else if (input_data[i][0] == "Scenario") {
        row_data = "## " + input_data[i][1];
      } else if (input_data[i][0] == "Step") {
        row_data = "* " + TAGS(input_data[i][2], input_data[i][3]);
      } else if (input_data[i][0] == "Tag") {
        row_data = "Tags: " + input_data[i][1].replace(/\s/, ''); // not sure what this is doing
      } else if (input_data[i][0] == "") {
        row_data = "";
      }
      data.push([row_data]); // data array MUST be a 2 dimensional array
  }
  sheet.getRange(1, 5, data.length, 1).setValues(data);
}

Я также создал рабочий пример, который вы можете проверить здесь: https://docs.google.com/spreadsheets/d/1q2SYD7nYubSuvkMOKQAFuGsrGzrMElzZNIFb8PjM7Yk/edit#gid = 0 (пришлите мне запрос, если он вам нужен). Он работает как талисман, используя событие onEdit для запуска calculateColumnE() с несколькими строками, мне интересно знать о результате на вашем листе 1000+ строк. Если это происходит медленно, вам может потребоваться запустить эту функцию вручную.

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

Не уверен, что это будет быстрее:

function TAGS(input,tr) {
  if (input.length > 0) {
    var lst = input.split(",");
    var i=0;
    tr=tr.replace(/<[^>]*>/g,function(){return '"' + lst[i++] + '"';});
  }
  return tr;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...