Скрипт для обобщения данных не обновляется

У меня есть электронная таблица Google с данными расписания; у него есть лист на каждый месяц, каждый лист состоит из шести блоков столбцов, по одному блоку на клиента.

Я создал сводную таблицу, которая показывает общую сумму для каждого клиента и отображает ее в виде списка:

function getClientTotals(sheetname, colcount)
{  
  colcount = colcount ? colcount : 6;
  var res;      
  var ss = SpreadsheetApp.openById('myid_goes_here');
  if(ss)
  {
    res = [];
    var totrow = ss.getRange(sheetname + '!A1:ZZ1').getValues()[0];
    for(var i = 0; i < totrow.length; i += colcount)
    {
      res.push([totrow[i], totrow[i + colcount - 1]]);
    }
  }   
  return res;
}

Затем я просто добавил ячейку в свой сводный лист, содержащий =getClientTotals($C$7,$C$8), который передает имя листа за месяц и количество столбцов для каждого клиента (в случае модификаций «схемы».

Все это работает нормально, но не обновляется при изменении исходных данных. Я добавил триггер onEdit; нет радости. Он обновляется, если вы перейдете в редактор сценариев и нажмете «Сохранить», но это бесполезно. Я что-то упускаю?


person Whelkaholism    schedule 26.01.2012    source источник
comment
Ничего не упущено; может помочь проголосовать за этот запрос функции в Google Issue Tracker: Issueetracker.google.com/issues/36763858 < / а>   -  person Timothy Johns    schedule 01.12.2017


Ответы (10)


Вам не хватает привередливой функции кеширования bug. Это работает так:

Google считает, что все ваши пользовательские функции зависят только от значений параметров, чтобы возвращать свой результат (при желании вы можете зависеть от других статических данных).

Учитывая это предварительное условие, они могут оценивать ваши функции только при изменении параметра. например

Предположим, у нас есть текст «10» в ячейке B1, затем в какой-то другой ячейке мы набираем =myFunction(B1)

myFunction будет оценена, и ее результат будет получен. Затем, если вы измените значение ячейки B1 на «35», custom будет переоценен, как ожидалось, и новый результат будет получен в обычном режиме. Теперь, если вы снова измените ячейку B1 на исходную «10», повторной оценки не будет, исходный результат будет немедленно извлечен из кеша.

Итак, когда вы используете имя листа в качестве параметра для его динамического извлечения и возврата результата, вы нарушаете правило кеширования.

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

person Henrique G. Abreu    schedule 26.01.2012
comment
Хммм, это раздражает, но спасибо за ответ! У меня есть неприятный обходной путь, добавив к функции фиктивный параметр; если я затем передам ссылку на ячейку, я могу принудительно обновить данные, просто увеличив число в этой ячейке. Не думайте, что в любом случае я могу создать кнопку обновления, которая будет делать это одним щелчком мыши, не так ли? Это было бы хорошо, на самом деле это не должно быть автоматическим, просто простым и очевидным. - person Whelkaholism; 27.01.2012
comment
Что ж, вы можете создать кнопку, на самом деле рисунок, и назначить ей функцию сценария, которая увеличит вашу фиктивную ячейку параметра, которая вызовет обновление. - person Henrique G. Abreu; 27.01.2012
comment
@ Рубен Я знаю, но почему я здесь упомянут? - person Zig Mandel; 17.02.2016
comment
@ZigMandel, потому что вчера был ваш комментарий, а теперь он исчез. - person Rubén; 17.02.2016
comment
@ Rubén aha, я думаю, вы видели этот комментарий здесь, он находится в другом ответе на этой же странице :) stackoverflow.com/a/11060267/2213940 - person Zig Mandel; 17.02.2016
comment
@ZigMandel. Я почти уверен, что видел этот комментарий здесь, а не там. Кстати, я тоже пометил его как устаревший. Я комментировал и отмечал, потому что, по моему опыту на других сайтах в сети Stack Exchange, обработка этих флагов занимает некоторое время. - person Rubén; 17.02.2016
comment
Я только что увидел, что вы из Перу. Вы уже слышали о es.stackoverflow.com? - person Rubén; 17.02.2016
comment
нет, нет, да :) нет: это не устарело, см. developers.google. com / apps-script / migration / нет: комментария здесь не было, я его не использовал неделями. да: Я из Перу, не видел, ты против ТАК на других языках :) - person Zig Mandel; 17.02.2016

Используйте в качестве параметра финансовую функцию Google. Like = GOOGLEFINANCE ("ВАЛЮТА: КАДАРЫ")

Эти функции принудительно перезагружаются каждые x минут

person user3813883    schedule 21.09.2019
comment
x = 20+ // минут - person Ismail; 15.01.2021

Я использую фиктивную переменную в функции, эта переменная относится к ячейке в электронной таблице. Затем у меня есть Myfunction() в скрипте, который записывает число Math.Random в эту ячейку.

MyFunction находится под триггерной службой (Редактировать / Текущие триггеры проекта), и вы можете выбирать различные триггеры событий, например, при открытии или по времени, там вы можете выбрать, например, период времени, от 1 минуты до месяца.

person Paulino Seoane    schedule 03.09.2018

еще одно решение проблемы кеширования.

в вашем методе есть фиктивная переменная. проходить

Filter(<the cell or cell range>,1=1)

как значение этого параметра.

e.g.

=getValueScript("B1","B4:Z10", filter(B4:Z10,1=1))

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

person Chamil    schedule 21.03.2014
comment
это больше не работает. Вы увидите ошибку. Эта функция не может ссылаться на ячейку с помощью NOW (), RAND () или RANDBETWEEN (), если вы попытаетесь сделать это таким образом. - person Arsen Ibragimov; 28.10.2015

У меня была аналогичная проблема с созданием панели инструментов для работы. Приведенное выше решение Chamil (а именно использование функции Sheet Filter, переданной в качестве значения фиктивной переменной в вашей функции) работает нормально, несмотря на более свежий комментарий Арсена. В моем случае я использовал функцию для отслеживания диапазона и не мог использовать фильтр для того же диапазона, поскольку он создавал циклическую ссылку. Итак, у меня была ячейка (в моем случае E45 в приведенном ниже коде), в которой я менял номер каждый раз, когда хотел, чтобы моя функция обновлялась:

=myFunction("E3:E43","D44",filter(E45,1=1))

Как указал Чамиль, фильтр в скрипте не используется:

function myFunction(range, colorRef, dummy) {
  variable 'dummy' not used in code here
}
person ART    schedule 27.01.2016

Поскольку скрипт приложения Google является расширением JS, функции должны иметь возможность обрабатывать больше аргументов, чем определено в сигнатуре функции, или меньше. Итак, если у вас есть такая функция, как

function ADD(a, b) {
  return CONSTANTS!$A$1 + a + b
}

тогда вы бы назвали эту функцию как

=ADD(A1, B1, $A$2)

где $ A $ 2 - это какой-то флажок (вставить -> флажок), который вы можете щелкнуть, чтобы «обновить» после того, как вам нужно было изменить значение из листа и ячейки КОНСТАНТЫ $ A $ 1

person James T.    schedule 06.06.2019

Что вы можете сделать, так это настроить другую ячейку где-нибудь в электронной таблице, которая будет обновляться каждый раз при добавлении нового листа. Убедитесь, что он обновляется не при каждом изменении, а только тогда, когда вы хотите выполнить расчет (в вашем случае, когда вы добавляете лист). Затем вы передаете ссылку на эту ячейку своей пользовательской функции. Как уже упоминалось, пользовательская функция может игнорировать этот параметр.

person theworldismyoyster    schedule 20.01.2015

Учитывая эту функцию, описанную Энрике Абреу, вы можете попробовать встроенную функцию электронных таблиц QUERY, этот понравившийся запрос SQL - это то, что я часто использую при работе с необработанными данными и получаю данные в виде сводки на другой вкладке, данные результатов обновляются в реальном времени после изменения необработанных данных.

Мое предложение основано на том факте, что в вашем скрипте нет расширенной работы, такой как выборка URL, а только работа с данными, так как без фактического чтения данных я не могу дать точное решение с помощью QUERY.

Что касается функции кеширования, упомянутой Энрике Абреу (у меня недостаточно репутации, чтобы комментировать его ответ), я провел тестирование и обнаружил, что:

  1. выглядит, что кеш не работает, скрипт функции тестирования показан ниже:

    функция сумматора (базовая) {Utilities.sleep (5000); возврат базы + 10; }

применяя эту настраиваемую функцию adder () на листе, вызывая ячейку, а затем меняя значение этой ячейки вперед и назад, каждый раз, когда я вижу сообщение о загрузке и общее время более 5 секунд. Это может быть связано с обновлением, упомянутым в этом Проблема с ГАЗом:

Теперь эта проблема исправлена. Пользовательские функции в New Sheets теперь учитывают контекст и не так активно кэшируют значения.

  1. проблема, упомянутая в этой теме, остается, мое тестирование показывает, что лист Google пересчитывает пользовательскую функцию каждый раз ТОЛЬКО КОГДА

    • value DIRECTLY called by function is changed.

    функция getCellValue (имя листа, строка, столбец) {var ss = SpreadsheetApp.getActiveSpreadsheet (); var sh = ss.getSheetByName (имя листа); return sh.getRange (строка, столбец) .getValue (); }

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

    • в листе изменена функция, содержащая расположение ячейки. бывший. вставить / удалить строку / столбец сверху или слева.
person Albert    schedule 16.02.2017

Я не хотел иметь фиктивный параметр. YMMV по этому поводу.

1 Ячейка «Список элементов», одна - «Обновить».

2 Скрипт с onEdit, если ячейка «Обновить»:

а) Очистите кеш документов

б) Заполнить кеш документов внешними данными (в моем случае таблица)

c) Для всех ячеек с моей пользовательской функцией getStockoData (...

  • получить формулу

  • установить '= 0'

  • установить изула

г) Установите ячейку в (1) со значением «Готово».

Это обновляет нужные вам биты, НО НЕ БЫСТРО.

person andrewdb    schedule 25.04.2018

Как сказал @Brionius, добавьте к функции дополнительный динамический аргумент. если вы используете now (), у вас могут возникнуть проблемы с тайм-аутом, поэтому обновление будет немного медленнее ...

cell A1 = int(now()*1000)
cell A2 = function(args..., A1)
person David Valdivieso    schedule 07.04.2014
comment
это больше не работает. Вы увидите ошибку. Эта функция не может ссылаться на ячейку с помощью NOW (), RAND () или RANDBETWEEN (), если вы попытаетесь сделать это таким образом. - person Arsen Ibragimov; 28.10.2015