J'ai une feuille de calcul générée par le système qui entre des cellules vides lorsqu'il y a plus d'un article dans un numéro de commande. Par exemple, si la commande 1 avait trois éléments, j'aurais trois lignes complètement remplies mais une seule avec la date. L'en-tête est comme ceci:
function myFunction() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getActiveSheet(); var last = sheet.getLastRow();// get last row number for (i = 2; i < last; i++) { var info = sheet.getRange(i, 3); Logger.log(info); if (info.isBlank()) { var data = sheet.getRange(i-1, 3).getValues(); //copy value from cell above with date sheet.getRange(i, 3).setValues(data); //paste value on empty cell } } }
J'ai joint un exemple d'image à partir d'un exemple de jeu de données:
J'ai essayé le code suivant qui fait beaucoup le travail mais je n'ai pas pu terminer la tâche car l'exécution expire à chaque fois que le script est exécuté ( il s'arrête autour de la ligne numéro 1 000). Ma feuille de calcul comporte environ 3 000 lignes et croît lentement. J'ai lu quelques instructions pour essayer de rendre le code plus efficace, mais pour moi, il est déjà très efficace (du moins en le comparant à VBA). Toute aide est appréciée!
Order Number | User | Date | Item
3 Réponses :
Le problème est que getRange
et d'autres services de feuille de calcul similaires ( Class SpreadsheetApp
) sont "très" lents.
Au lieu de lire une plage à chaque pour
itération, lisez toute la plage de données à la fois en utilisant getDataRange ()
puis getValues ()
puis itérer sur le tableau contenant toutes les valeurs de la plage de données.
En relation
J'ai pensé que lorsqu'un exemple de script modifié pour la situation d'OP est proposé, cela pourrait aider à comprendre les points de modification. Je l'ai donc proposé comme l'une des nombreuses modifications.
Merci pour votre commentaire @Tanaike. J'hésite à le faire alors qu'il y a déjà beaucoup de questions similaires et que le PO n'a pas inclus une brève description de leurs efforts de recherche / recherche. Quoi qu'il en soit, je suis heureux que vous ayez publié une réponse :)
Merci d'avoir répondu. Je peux comprendre. Je pensais que lorsque l'utilisateur pouvait obtenir la direction pour résoudre le problème de l'utilisateur, cela pouvait conduire à l'éducation en tant qu'utilisateur. Alors j'ai proposé à ce sujet. Mais bien sûr, lorsque je pourrais trouver la question clairement dupliquée pour résoudre le problème, je voudrais proposer de la renvoyer.
Ruben, merci pour le matériel. Je vais lire les articles que vous avez publiés. En fait, je suis nouveau dans javascript et Google Sheets (je fais généralement un peu de Python ou VBA pour les petites tâches) et je n'étais pas au courant de la lenteur du processus derrière getRange
et d'autres services de feuille de calcul. J'ai essayé de rechercher des questions similaires, mais je me suis retrouvé à lire comment rendre le code efficace, ce qui est un grand pas en avant pour un nouvel utilisateur.
Je pense que la raison de votre problème est que getValues
et setValues
sont utilisés dans la boucle. De ce fait, le coût du processus sera élevé. Cela a déjà été mentionné dans la réponse de Rubén . Donc, afin de réduire le coût, dans votre situation, que diriez-vous de la modification avec le flux suivant?
getValues
. setValues
. Lorsque le flux ci-dessus est reflété dans votre script, il devient comme suit.
function myFunction() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getActiveSheet(); var last = sheet.getLastRow();// get last row number // I modified below script. var range = sheet.getRange("C2:C" + last); // 1. Retrieve values from the column "C". var values = range.getValues(); // 2. Create an array for putting values to Spreadsheet. var temp = ""; var v = values.map(([c]) => [c.toString() != "" ? temp = c : temp]); // 3. Put the created array to the Spreadsheet. range.setValues(v); }
Cela a parfaitement fonctionné! Et merci pour le matériel de référence.
@Haddocks Merci d'avoir répondu. Je suis content que votre problème ait été résolu.
Essayez ceci:
function myFunction() { var ss=SpreadsheetApp.getActive(); var sh=ss.getActiveSheet() var shsr=2;//data start row var vs=sh.getRange(shsr,3,sh.getLastRow()-shsr+1,1).getValues(); vs.forEach(function(r,i){if(!r[0]){vs[i][0]=vs[i-1][0];}}); sh.getRange(shsr,3,sh.getLastRow()-shsr+1,1).setValues(vs); }
Cela a également fonctionné. Merci Cooper pour la solution!