1
votes

Copier et coller les données dans la ligne vide suivante

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:

 Image du 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


0 commentaires

3 Réponses :


1
votes

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


4 commentaires

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.



2
votes

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?

  1. Récupérez les valeurs de la colonne "C" à l'aide de getValues ​​.
  2. Créez un tableau pour placer des valeurs dans une feuille de calcul.
  3. Placez le tableau créé dans la feuille de calcul à l'aide de setValues ​​.

Lorsque le flux ci-dessus est reflété dans votre script, il devient comme suit.

Script modifié:

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);
}

Références: h3>


2 commentaires

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.



0
votes

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);
}


1 commentaires

Cela a également fonctionné. Merci Cooper pour la solution!