Обновить данные, полученные пользовательской функцией в Google Sheet

Я написал пользовательский скрипт Google Apps, который получит id и получить информацию из веб-службы (цена).

Я использую этот скрипт в электронной таблице, и он отлично работает. Моя проблема в том, что эти цены меняются, и моя электронная таблица не обновляется.

Как я могу заставить его повторно запустить скрипт и обновить ячейки (без ручного просмотра каждой ячейки)?

6 ответов


Ok, похоже, моя проблема заключалась в том, что google ведет себя странно - он не перезапускает сценарий, пока параметры сценария похожи, он использует кэшированные результаты предыдущих запусков. Следовательно, он не повторно подключается к API и не повторно получает цену, он просто возвращает предыдущий результат сценария, который был кэширован.

см. больше информации здесь:https://code.google.com/p/google-apps-script-issues/issues/detail?id=888

и здесь: скрипт для суммирования данных не обновляется

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

поэтому всякий раз, когда я вызываю функцию, для дополнительного параметра я передаю "$a$1". Я также создал пункт меню под названием refresh, и когда я его запускаю, он помещает текущая дата и время в A1, следовательно, все вызовы скрипта с $A$1 в качестве второго параметра придется пересчитать. Вот код из моего скрипта:

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Refresh",
    functionName : "refreshLastUpdate"
  }];
  sheet.addMenu("Refresh", entries);
};

function refreshLastUpdate() {
  SpreadsheetApp.getActiveSpreadsheet().getRange('A1').setValue(new Date().toTimeString());
}

function getPrice(itemId, datetime) {
  var headers =
      {
        "method" : "get",
        "contentType" : "application/json",
        headers : {'Cache-Control' : 'max-age=0'}
      };

  var jsonResponse = UrlFetchApp.fetch("http://someURL?item_id=" + itemId, headers);
  var jsonObj = eval( '(' + jsonResponse + ')' );
  return jsonObj.Price;
  SpreadsheetApp.flush();
}   

и когда я хочу поместить цену товара с ID 5 в ячейку, Я использую следующую формулу:

=getPrice(5, $A)

когда я хочу обновить цены, я просто нажимаю "обновить" -> "обновить" пункт меню. Помните, что вам нужно перезагрузить электронную таблицу после изменения onOpen() сценарий.


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

что я был похож на tbkn23.

функция, которую я хочу переоценить, имеет дополнительный неиспользуемый параметр $A$1. Таким образом, вызов функции

=myFunction(firstParam, $A)

но в коде сигнатура функции

function myFunction(firstParam)

вместо функции обновления я использовал функцию onEdit(e), как это

function onEdit(e)
{
   SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random());
}

этот функция запускается при редактировании любой ячейки электронной таблицы. Итак, теперь вы редактируете ячейку, случайное число помещается в A1, это обновляет список параметров, как предложил tbkn23, что приводит к переоценке пользовательской функции.


Это очень поздно, и я не знаю, было бы полезно, но на самом деле сидят здесь можно сделать NOW() автоматическое обновление

enter image description here


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

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


это может быть супер старый поток, но может быть полезно для кого-то, кто пытается это сделать, как я только что.

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

Итак, объявление типа: function myFunction (firstParam, dummy) , а затем вызов его будет быть, как было предложено. Это сработало для меня.

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

function onEdit(e)
{
  e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random());
}

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

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