Escribí un script de Google Apps personalizado que recibirá id
y obtendrá información de un servicio web (un precio).
Utilizo este script en una hoja de cálculo y funciona bien. Mi problema es que estos precios cambian y mi hoja de cálculo no se actualiza.
¿Cómo puedo obligarlo a volver a ejecutar el script y actualizar las celdas (sin revisar manualmente cada celda)?
Respuestas:
Ok, parece que mi problema fue que Google se comporta de una manera extraña: no vuelve a ejecutar el script siempre que los parámetros del script sean similares, usa resultados almacenados en caché de las ejecuciones anteriores. Por lo tanto, no se vuelve a conectar a la API y no recupera el precio, simplemente devuelve el resultado del script anterior que se almacenó en caché.
Vea más información aquí: https://code.google.com/p/google-apps-script-issues/issues/detail?id=888
y aquí: Script para resumir los datos que no se actualizan
Mi solución fue agregar otro parámetro a mi script, que ni siquiera uso. Ahora, cuando llame a la función con un parámetro que sea diferente a las llamadas anteriores, tendrá que volver a ejecutar el script porque el resultado de estos parámetros no estará en la caché.
Entonces, cada vez que llamo a la función, para el parámetro adicional paso "$ A $ 1". También creé un elemento de menú llamado actualizar, y cuando lo ejecuto, pone la fecha y hora actual en A1, por lo tanto, todas las llamadas al script con $ A $ 1 como segundo parámetro tendrán que recalcularse. Aquí hay un código de mi 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(); }
Y cuando quiero poner el precio del artículo con ID 5 en una celda, uso la siguiente fórmula:
=getPrice(5, $A$1)
Cuando quiero actualizar los precios, simplemente hago clic en el elemento de menú "Actualizar" -> "Actualizar". Recuerde que debe volver a cargar la hoja de cálculo después de cambiar la
onOpen()
secuencia de comandos.fuente
Sé que esta es una pregunta un poco vieja. Pero este método no requiere ninguna acción del usuario excepto realizar un cambio.
Lo que hice fue similar a tbkn23.
La función que quiero reevaluar tiene un parámetro adicional no utilizado, $ A $ 1. Entonces la llamada a la función es
=myFunction(firstParam, $A$1)
Pero en el código, la firma de la función es
function myFunction(firstParam)
En lugar de tener una función de actualización, he usado la función onEdit (e) como esta
function onEdit(e) { SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random()); }
Esta función se activa siempre que se edita cualquier celda de la hoja de cálculo. Entonces, ahora edita una celda, se coloca un número aleatorio en A1, esto actualiza la lista de parámetros como sugirió tbkn23, lo que hace que la función personalizada sea reevaluada.
fuente
Esto es muy tarde y no sé si sería útil, pero en realidad hay una configuración aquí que puede
NOW()
actualizar automáticamentefuente
NOW()
es una función incorporada, no una función personalizada.Si su función personalizada está dentro de una columna específica, simplemente ordene su hoja de cálculo por esa columna.
La acción de ordenar fuerza una actualización de los datos, que invoca su función personalizada para todas las filas de esa columna a la vez.
fuente
Este puede ser un hilo muy antiguo, pero puede ser útil para alguien que intente hacer esto, como lo estaba haciendo yo.
Trabajando con el script de Lexi tal como está, parece que ya no funciona con las Hojas de cálculo actuales, pero si agrego la variable ficticia en mi función como parámetro (no es necesario usarla dentro de la función), de hecho lo hará Obligar a Google Sheets a actualizar la página nuevamente.
Entonces, una declaración como: function myFunction (firstParam, dummy) y luego llamarlo sería como se ha sugerido. Eso funcionó para mí.
Además, si es una molestia que una variable aleatoria aparezca en todas las hojas que edita, una solución fácil para limitar a una hoja es la siguiente:
function onEdit(e) { e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random()); }
fuente
Lógica de script:
Retazo:
/*@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) + ')' ); }
Leer:
fuente
Como se menciono anteriormente:
La posible solución es crear una casilla de verificación en una sola celda y usar esta celda como argumento para la función personalizada:
=myFunction(A1)
fuente
Si ha escrito una función personalizada y la ha utilizado en su hoja de cálculo como fórmula, cada vez que abra la hoja de cálculo o se modifique cualquier celda de referencia, la fórmula se volverá a calcular.
Si solo desea seguir mirando la hoja de cálculo y desea que sus valores cambien, considere agregar un disparador temporizado que actualice las celdas. Lea más sobre los desencadenantes aquí.
fuente