web-dev-qa-db-fra.com

Actualiser les données récupérées par une fonction personnalisée dans Google Sheet

J'ai écrit un script Google Apps personnalisé qui recevra un id et récupérera les informations d'un service Web (un prix).

J'utilise ce script dans un tableur, et cela fonctionne très bien. Mon problème est que ces prix changent et que mon tableur n'est pas mis à jour.

Comment puis-je le forcer à réexécuter le script et à mettre à jour les cellules (sans passer manuellement sur chaque cellule)?

74
tbkn23

Ok, il semble que mon problème soit que Google se comporte de manière étrange - il ne ré-exécute pas le script tant que ses paramètres sont similaires, il utilise les résultats mis en cache des exécutions précédentes. Par conséquent, il ne se reconnecte pas à l'API et ne récupère pas le prix, il renvoie simplement le résultat du script précédent qui avait été mis en cache.

Voir plus d'informations ici: https://code.google.com/p/google-apps-script-issues/issues/detail?id=888

et ici: Script pour résumer les données non mises à jour

Ma solution a été d'ajouter un autre paramètre à mon script, que je n'utilise même pas. Désormais, lorsque vous appelez la fonction avec un paramètre différent des appels précédents, elle devra réexécuter le script car le résultat de ces paramètres ne sera pas dans le cache.

Donc, chaque fois que j'appelle la fonction, pour le paramètre supplémentaire, je passe "$ A $ 1". J'ai également créé un élément de menu appelé actualisation. Lorsque je l'exécute, il met la date et l'heure actuelles en A1. Tous les appels au script avec $ A $ 1 en tant que second paramètre devront alors être recalculés. Voici du code de mon 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();
}   

Et quand je veux mettre le prix d'un article avec l'ID 5 dans une cellule, j'utilise la formule suivante:

=getPrice(5, $A$1)

Lorsque je veux actualiser les prix, je clique simplement sur l'élément de menu "Actualiser" -> "Actualiser". N'oubliez pas que vous devez recharger la feuille de calcul après avoir modifié le script onOpen().

78
tbkn23

Je sais que c'est une question un peu ancienne. Mais cette méthode ne nécessite aucune action de la part de l'utilisateur, sauf une modification.

Ce que j'ai fait était similaire à tbkn23.

La fonction que je veux réévaluer a un paramètre inutilisé supplémentaire, $ A $ 1. Donc, l'appel de fonction est

=myFunction(firstParam, $A$1)

Mais dans le code, la signature de la fonction est

function myFunction(firstParam)

Au lieu d'avoir une fonction Refresh, j'ai utilisé la fonction onEdit (e) comme ceci

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

Cette fonction est déclenchée chaque fois qu'une cellule de la feuille de calcul est modifiée. Alors maintenant que vous éditez une cellule, un nombre aléatoire est placé dans A1, cela actualise la liste des paramètres comme suggéré par tbkn23, ce qui entraîne la réévaluation de la fonction personnalisée.

32
Lexi Brush

C’est très tard et je ne sais pas si ce serait utile, mais en fait, il est possible de faire en sorte que NOW() se mette à jour automatiquement

enter image description here

12
Thaina

Si vous êtes une fonction personnalisée dans une colonne spécifique, il vous suffit de classer votre feuille de calcul en fonction de cette colonne.

L'ordre impose une actualisation des données, qui appelle votre fonction personnalisée pour toutes les lignes de cette colonne à la fois.

4
flu

C'est peut-être un très vieux fil, mais peut être utile pour quelqu'un qui essaie de le faire, comme je viens de le faire.

En travaillant hors du script de Lexi tel quel, cela ne semblait plus fonctionner avec les Sheets actuelles, mais si j'ajoute la variable factice dans ma fonction en tant que paramètre (inutile de l'utiliser dans la fonction), ce sera effectivement le cas. forcer les feuilles de Google pour actualiser la page à nouveau.

Ainsi, une déclaration du type: function myFunction (firstParam, dummy) et l’appeler ensuite seraient comme il a été suggéré. Cela a fonctionné pour moi.

De plus, s'il est gênant qu'une variable aléatoire apparaisse sur toutes vos feuilles que vous modifiez, une solution facile pour limiter à une feuille est la suivante:

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

Chaque fois que vous déployez votre application Web, elle utilise la même version. C'est pourquoi il ne met pas à jour.

Une fois les modifications apportées, sélectionnez Fichier-> Gérer les versions et enregistrez la nouvelle version. La nouvelle version apparaît. Ensuite, lorsque vous déployez, choisissez la version que vous souhaitez exécuter enter image description here

0
Azamat Mahkamov