#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 только из — за другой интеграции, которая нуждается в ней, поэтому она запускает новую запись-поэтому обычно расчет действительно выполняется один раз, и нет необходимости пересчитывать для всех. Нужны архитектурные рекомендации относительно того, как сохранить эту производительность. Спасибо.