Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

Подробнее см. здесь: https://code.google.com/p/google-apps-script-issues/issues/detail?id=888

и здесь: Script, чтобы суммировать данные, не обновляемые

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

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

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();
}   

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

=getPrice(5, $A$1)

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

Ответ 2

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

То, что я сделал, было похоже на tbkn23.

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

=myFunction(firstParam, $A$1)

Но в коде подпись функции

function myFunction(firstParam)

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

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

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

Ответ 3

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

введите описание изображения здесь

Ответ 4

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

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

Ответ 5

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

После внесения изменений перейдите в File-> Управление версиями и сохраните новую версию. Новая версия появляется. Затем при развертывании выберите версию, которую хотите запустить enter image description here

Ответ 6

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

Отключение Lexi script as-is, похоже, больше не работает с текущими листами, но если я добавлю фиктивную переменную в свою функцию в качестве параметра (нет необходимости фактически использовать ее внутри функции), это действительно заставит листы Google обновлять страницу еще раз.

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

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

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

Ответ 7

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

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