Я написал собственный скрипт Google Apps, который будет получать id
и извлекать информацию из веб-службы (цена).
Я использую этот сценарий в электронной таблице, и он отлично работает. Моя проблема в том, что эти цены меняются, а моя таблица не обновляется.
Как я могу заставить его повторно запустить скрипт и обновить ячейки (без ручного обхода каждой ячейки)?
Ответы:
Хорошо, похоже, моя проблема заключалась в том, что Google ведет себя странным образом - он не перезапускает скрипт, пока параметры скрипта похожи, он использует кешированные результаты из предыдущих запусков. Следовательно, он не повторно подключается к API и не получает повторно цену, он просто возвращает предыдущий результат скрипта, который был кэширован.
См. Дополнительную информацию здесь: https://code.google.com/p/google-apps-script-issues/issues/detail?id=888
и здесь: Скрипт для обобщения данных, не обновляющихся
Мое решение заключалось в том, чтобы добавить в свой скрипт еще один параметр, который я даже не использую. Теперь, когда вы вызываете функцию с параметром, который отличается от предыдущих вызовов, ей придется повторно запустить скрипт, потому что результат для этих параметров не будет в кеше.
Поэтому всякий раз, когда я вызываю функцию, в качестве дополнительного параметра я передаю «$ A $ 1». Я также создал пункт меню под названием «Обновить», и когда я его запускаю, он помещает текущую дату и время в 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$1)
Когда я хочу обновить цены, я просто нажимаю пункт меню «Обновить» -> «Обновить». Помните, что вам необходимо перезагрузить электронную таблицу после изменения
onOpen()
сценария.источник
Я знаю, что это немного старый вопрос. Но этот метод не требует от пользователя каких-либо действий, кроме внесения изменений.
То, что я сделал, было похоже на tbkn23.
Функция, которую я хочу переоценить, имеет лишний неиспользуемый параметр $ A $ 1. Итак, вызов функции
=myFunction(firstParam, $A$1)
Но в коде подпись функции
function myFunction(firstParam)
Вместо функции обновления я использовал функцию onEdit (e), подобную этой
function onEdit(e) { SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random()); }
Эта функция запускается всякий раз, когда редактируется какая-либо ячейка в электронной таблице. Итак, теперь вы редактируете ячейку, случайное число помещается в A1, это обновляет список параметров, как было предложено tbkn23, что приводит к повторной оценке настраиваемой функции.
источник
Это очень поздно, и я не знаю, что это было бы полезно, но на самом деле здесь есть настройки, вы можете
NOW()
автоматически обновлятьисточник
NOW()
это встроенная функция, а не пользовательская функция.Если ваша настраиваемая функция находится внутри определенного столбца, просто упорядочивайте электронную таблицу по этому столбцу.
Действие упорядочивания вызывает обновление данных, которое вызывает вашу пользовательскую функцию сразу для всех строк этого столбца.
источник
Это может быть очень старая ветка, но может быть полезна для тех, кто пытается это сделать, как и я только что.
Работая с скриптом Lexi как есть, он, похоже, больше не работал с текущими таблицами, но если я добавлю фиктивную переменную в свою функцию в качестве параметра (нет необходимости фактически использовать ее внутри функции), она действительно будет заставить листы Google снова обновить страницу.
Итак, объявление типа: function myFunction (firstParam, dummy) с последующим его вызовом будет таким, как было предложено. Это сработало для меня.
Кроме того, если случайная переменная появляется на всех ваших листах, которые вы редактируете, неудобно, простое решение ограничиться одним листом:
function onEdit(e) { e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random()); }
источник
Логика скрипта:
Фрагмент:
/*@customfunction*/ function sheetNames(e) { return SpreadsheetApp.getActive() .getSheets() .map(function(sheet) { return sheet.getName(); }); } /*Create a installable trigger to listen to grid changes on the sheet*/ function onChange(e) { if (!/GRID/.test(e.changeType)) return; //Listen only to grid change SpreadsheetApp.getActive() .createTextFinder('=SHEETNAMES\\([^)]*\\)') .matchFormulaText(true) .matchCase(false) .useRegularExpression(true) .replaceAllWith( '=SHEETNAMES(' + (Math.floor(Math.random() * 500) + 1) + ')' ); }
Читать:
источник
Как отмечалось ранее:
Возможное решение - создать флажок в одной ячейке и использовать эту ячейку в качестве аргумента для пользовательской функции:
=myFunction(A1)
источник
Если вы написали настраиваемую функцию и использовали ее в своей электронной таблице как формулу, то каждый раз, когда вы открываете электронную таблицу или любую ссылочную ячейку, формула пересчитывается.
Если вы хотите просто смотреть в электронную таблицу и изменять ее значения, подумайте о добавлении синхронизированного триггера, который обновит ячейки. Подробнее о триггерах здесь
источник