Запуск обновления функции при использовании ArrayFormula

#google-apps-script #google-sheets

Вопрос:

Я сталкиваюсь с проблемой, когда мне нужно убедиться, что Google sheets запускает обновление ячеек при изменении данных. По разным причинам настройка моего листа заключается в том, что у меня есть расчет/логин ArrayFormula в заголовке ячейки, и это, по сути, вычислит все строки под ней. Для простоты мои уравнения имеют форму массива и передают значение, такое как «C2:C», что в конечном итоге означает » пожалуйста, дайте мне значение столбца C для данной строки. Таким образом, у меня может быть что — то вроде ArrayFormula(C2:C 1), что на самом деле означает » дайте мне столбец C моей текущей строки и добавьте один.

Теперь ПРОБЛЕМА в том, что я создаю пользовательскую функцию, назовем ее Foo, и я хочу также передать ей «Столбец C данной строки» — так, допустим, теперь моя ArrayFormula выглядит так: ArrayFormula(Foo(C2:C)).

Проблема в том, что, я полагаю, из-за того, как google таблицы пытаются грамотно кэшировать вызовы функций, он не распознает, когда изменяется значение, и пересчитывает вызов. Google таблицы видят, что «C2:C» вообще не изменился, поэтому он не обновит его, даже если я действительно изменил значение столбца C данной строки.

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

Я создал хороший тестовый пример этого со следующим листом Google: https://docs.google.com/spreadsheets/d/1fCiRSiuII-2vOWJD9LWWkh9qjK0P_dZskofwBYxiZUI/edit?usp=sharing

Если вы заметили, у меня есть две колонки: Total Sft и «Total sqft New». Оба они должны генерировать одно и то же значение. В первом я сделал умножение вручную — например, A2:A*B2:B, — которое генерирует ожидаемый результат. Во втором столбце вместо ручного множественного уравнения я создал тестовую функцию под названием testFunctionMultiply, которая делает то же самое — умножает значения.

Как вы можете видеть, столбцы показывают разные значения, когда я ожидал, что они совпадут. Мысли?

Ответ №1:

Arrayformula работает не для каждой функции. Как, например, собственная функция DGET. Если вы измените функцию так, чтобы она принимала массив, то она будет работать должным образом. Вот копия с вашего листа.

Формула сейчас такова:

 ={"Total Sqft New";ARRAYFORMULA(IF(ISBLANK(Sheet1!A2:A),,testFunctionMultiply(A2:A,B2:B)))}
 

Сценарий:

 function testFunctionMultiply(param1, param2) {
  const arg1 = param1.flat()
  const arg2 = param2.flat()
  const output = []

  for (i = 0; i < arg1.length; i  ){
    output.push([Number(arg1[i])*Number(arg2[i])])
  }

  return output
}
 

совет:

Не используйте «» в качестве нулевого значения. Скрипт Google apps обнаружит это, например, в методе .getLastRow ().

 //Wrong:
=IF(A2 = "","","Not blank"

//Good:
=IF(A2 = "",,"Not blank:
 

Комментарии:

1. Спасибо! Это помогает мне лучше понять, чего мне не хватает. Но одна критическая проблема связана с вышесказанным, это приводит к пересчету при каждой новой записи строки, не так ли? Прямо сейчас у меня возникают проблемы с тайм-аутом. Есть какие-нибудь умные решения, чтобы обойти это, чтобы он вычислял только для новых записей?

2. Таков принцип arrayformula. Или измените сценарий, который не возвращается в пользовательскую функцию, а вставляет значения в сам лист. Затем вы можете перезапустить этот сценарий с помощью меню/ярлыка/кнопки/триггера таймера. Затем вы (или триггер) запускаетесь, когда закончите добавлять строки.

3. привет, Ремко — извините, я не понял вашего комментария. Не могли бы вы, пожалуйста, объяснить еще раз? Поскольку мой лист содержит тысячи строк, и, честно говоря, я использую arrayformula только из — за другой интеграции, которая нуждается в ней, поэтому она запускает новую запись-поэтому обычно расчет действительно выполняется один раз, и нет необходимости пересчитывать для всех. Нужны архитектурные рекомендации относительно того, как сохранить эту производительность. Спасибо.