J’ai une petite question concernant la fonction importxml de GoogleSheet.
J’ai ajouté cette fonction sur 450 lignes, le problème est que je n’arrive pas à avoir tous les résultats au même moment : la fonction se lançant en continue, j’ai beaucoup de cellules indiquant le résultat « Loading ».
Y’a t-il un moyen de « programmer » cette fonction ? De faire en sorte qu’elle ne se lance qu’une fois / jour ?
Mais quand je relance le script, toutes les valeurs retournées sont égales à « 0 » .
Je pense que le problème vient de la :
_« Note: In case you’re wondering why we’re adding a random number to the end of our URL, it’s because otherwise the website will be cached and the function stops importing the latest data. »
Les 450 itérations s’exécutent de manière séquentielles les unes après les autres, le temps d’attente est donc très long, il faudrait être en mesure de lancer les 450 itérations en asynchrone pour qu’elles s’exécutent en //
D’autre part, il faut créer une fonction via un Google App Script lié directement à la Google Spreadsheet, et programmer l’exécution de cette fonction via le déclenchement d’un time-driven trigger, afin de pouvoir lancer l’extract et mise à jour des données quotidiennement.
Je reprends ce que disait Brice:
2 mécanismes entrent en jeu ici:
Google met en cache les requêtes que tu executes (logique)
La requete n’est executée qu’une fois, à sa création ou à l’ouverture du fichier (au bémol près mentionné en #1)
pour faire ce que tu veux, il faut donc avoir la possibilité d’excuter la requete a intervalle régulier, et non une seule fois. Importxml n’est pas fait pour ca, les google script le sont: https://www.google.com/script/start/
Je pense personnellement qu’on atteint ici très vite les limites de la fonction importxml qui n’est pas faite pour cela, d’autant plus qu’on va demander de travailler ligne par ligne… et lorsqu’on se penche sur la mécanique de fonctionnement de mise à jour des cellules dans les spreadsheet, on comprend vite qu’il faut en réalité faire un post-traitement de type: calcul de toutes les valeurs à injecter avant, puis update du contenu des cellules en une fois, via une operation de range .
Pour donner un exemple du genre de code qui peut faire fuir assez rapidement…(à noter que dans mon exemple , je voulais au contraire faire un traitement synchrone alors que la boucle forEach est de par nature asynchrone).
Ici le processus est en deux étapes: 1ère étape, on fait notre calcul interne des valeurs à injecter, hors feuille, puis 2ième étape, on met à jour directement un range de cellules avec les valeurs précédemment calculées:
// Let's get our new data rows from some API call's JSON results
var datarows = jsonapicall(apiurl);
// Compte the rows headers
var fields = Object.keys(datarows[0]);
var rows = [];
// Step 1 - For each JSON row retrieved, compute the spreadsheet row values to be inserted
datarows.forEach(function(element, index){
// Since forEach is aynchronous in JS, let's make it synchronous
(function(elem, idx) {
var currentpos = idx+1;
var rowdata=[];
// Foreach field of data in our JSON row, compute the associated spreadsheet current row cell value
for(var fieldindex in fields) {
var field= fields[fieldindex];
if(elem.hasOwnProperty(field))
rowdata.push(elem[field]); //Logger.log("Treating field '"+field+"', which value is='"+element[field]+"'");
else
rowdata.push(""); //Logger.log("Treating empty field '"+field+"'");
}
rows.push(rowdata);
})(element, index);
});
var sheet = SpreadsheetApp.getActiveSheet();
// Step 2 - Update the Spreadsheet cells values with previously computed data rows
var range = sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length);
range.setValues(rows);