Script Archivage

Bonjour,

Dans ce post : https://forum.excel-pratique.com/sheets/deplacer-des-lignes-dans-une-autre-feuille-en-fonction-d-une...

Steelson écrit:

Si tu veux déplacer, adapte ce programme dit d'archivage en fonctionne des noms de feuilles et colonne concernées, mets un lien vers un fichier GSheets si besoin.

Ici

la feuille initial s'appelle prêt,

la destination est archive,

le critère est une case à cocher colonne 6,

et les données de A à K

archiver
--------

function onEdit(event){
var feuille = event.source.getActiveSheet();
var cel = event.source.getActiveRange();
if ((cel.getColumn() == 6) && (feuille.getName().toString() == 'prêt')){
if (cel.getValue()){
var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("archive");
archive.insertRowBefore(2);
var plage = feuille.getRange('A' + cel.getRow() + ':K' + cel.getRow());
plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
feuille.getRange('G' + cel.getRow() + ':K' + cel.getRow()).clearContent();
}
}
};

J'essaye d'adapter pour que le script se déclenche en appuyant sur un bouton.

J'ai modifié le script comme ceci:

function Archiver() {
  var feuille = event.source.getActiveSheet();
  var cel = event.source.getActiveRange();
  if ((cel.getColumn() == 5) && (feuille.getName().toString() == 'Courriers')){
    if (cel.getValue()){
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + cel.getRow() + ':F' + cel.getRow());
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      feuille.getRange('E' + cel.getRow() + ':F' + cel.getRow()).clearContent();
    }
  }
};

La feuille initiale s'appelle "Courriers", la feuille de destination "Archive", le critère est une case à cocher colonne 5 (E) et la plage de donnée de A à F.

Lorsque j'exécute le script, j'ai le message suivant: "ReferenceError: event is not defined"

Avec mes faibles connaissances, je ne parviens pas à trouver la solution.

Question subsidiaire: Par quoi devrais-je commencer pour apprendre ce langage?

Merci d'avance

Bonjour,

en effet, event fait référence à .. un événement capté par la fonction réservée onEdit(event)

je regarde rapidement ...

le logique, le squelette du script est alors le suivant (au lieu d'un événement)

function archiver(){
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Courriers");
  var lastRow = feuille.getLastRow();
  for (var i=2; i<=lastRow; i++){
    if (feuille.getRange('E' + i).getValue()) {

// ici code d'archivage

    }
  }
}

Pour apprendre le langage, le mieux c'est de faire ce que tu fais ... essaie, recopie, tente de comprendre, et ensuite documente toi sur les fonctions

function archiver(){
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Courriers");
  var lastRow = feuille.getLastRow();
  for (var i=2; i<=lastRow; i++){
    if (feuille.getRange('E' + i).getValue()) {

      // ici code d'archivage
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + i + ':F' + i);
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      // est-ce que tu veux supprimer la ligne initiale ?

    }
  }
}

pas testé ...

Bonjour,

Merci pour le script qui fonctionne très bien.

Les lignes sélectionnées sont bien copiées vers la feuille Archive.

Serait-il possible que la sélection copie soit effacée de la feuille Courriers?

J'ai essayé de remplacer copyTo par moveTo mais j'ai un message d'erreur.

J'ai essayé aussi avec copyRange.clear(); mais soit ce n'est pas correct soit je le place mal.

Autre petite demande, ma ligne de titre ne contient pas de case à cocher mais elle est recopiée systématiquement sur la feuille Archive.

Une idée pour qu'elle ne soit pas reprise dans la sélection?

Merci d'avance

En quelle ligne se trouve la ligne de titre ? si tu ne postes jamais de lien vers ton fichier je travaille en aveugle.

Si la ligne de titre est en 2 ... et pour la suppression ...

function archiver(){
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Courriers");
  var lastRow = feuille.getLastRow();
  for (var i=lastRow; i>2; i--){
    if (feuille.getRange('E' + i).getValue()) {

      // ici code d'archivage
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + i + ':F' + i);
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      feuille.deleteRow(i);

    }
  }
}

Voici le lien : https://docs.google.com/spreadsheets/d/1PiCIVroQEydsdpaL5ugvuDAyR-JeGq6mVVRnIgKTjJM/edit?usp=sharing

Je viens de tester le script. J'ai un message "Exécution du script" qui reste figé et ensuite un autre message qui me dit que le délai d'exécution est trop long.

J'ai repris ton premier script et j'ai ajouté la dernière ligne.

function Archiver(){
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Courriers");
  var lastRow = feuille.getLastRow();
  for (var i=2; i<=lastRow; i++){
    if (feuille.getRange('E' + i).getValue()) {

      // ici code d'archivage
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + i + ':F' + i);
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      feuille.deleteRow(i);

    }
  }
}

Ca fonctionne mais lorsqu'il y a plusieurs lignes cochées, il en oublie parfois.

Le délai du script est long car tu as plus de 4000 lignes à traiter ! parce que les lignes avec des checkboxes sont supposées "actives". Donc feuille.getLastRow(); n'est pas adapté. Note aussi que comme tu as demandé la suppression de la ligne, je dois partir de lastRow et remonter.

Au passage, si tu n'as pas besoin de tant de lignes, supprime les, même pour n'en garder que 100.

Si toutes les cellules de A sont remplies, on peut faire :

  var values = feuille.getRange('A6:A').getValues().join().split(","); 
  var ligne = values.indexOf("") + 6;

donc essaie avec ceci

function Archiver(){
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Courriers");
  var values = feuille.getRange('A6:A').getValues().join().split(","); 
  var lastRow = values.indexOf("") + 6;
  for (var i=lastRow; i>6; i--){
    if (feuille.getRange('E' + i).getValue()) {

      // ici code d'archivage
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + i + ':F' + i);
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      feuille.deleteRow(i);

    }
  }
}

mais si un jour il y avait beaucoup de lignes, je préconise de plutôt revenir à onEdit(event) qui le fera au coup par coup quand tu cliqueras que une checkbox.

Bonjour,

une petite erreur de Mike qui a oublié de finir sa condition Si

if (feuille.getRange('E' + i).getValue()=== true) {

merci Gilbert ... mais in fine cela marche quand même ?

Le script fonctionne bien.

J'ai tant de ligne car nous avons régulièrement 100 à 150 courriers inscrits en même temps sur la liste.

Chaque fois qu'une ligne est supprimée, cela diminue le nombre de lignes.

Donc d'ici environ un mois, les 4000 lignes auront disparus et il faudra en rajouter.

Comme mes collègues ne sont pas toujours des lumières en informatique, j'avais laissé de la marge...

Je ne sais pas s'il est possible d'ajouter une ligné automatiquement lorsque la dernière est complétée.

Si ce n'est pas exagéré, pourrais-tu me montrer le script avec onEdit(event)?

Je montrerai les deux solutions et l'équipe choisira.

Merci beaucoup pour le temps passé

Si ce n'est pas exagéré, pourrais-tu me montrer le script avec onEdit(event)?

function onEdit(event){
  var feuille = event.source.getActiveSheet();
  var cel = event.source.getActiveRange();
  if ((cel.getColumn() == 5) && (feuille.getName().toString() == 'Courriers')){
    if (cel.getValue()===true){
      var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("archive");
      archive.insertRowBefore(2);
      var plage = feuille.getRange('A' + cel.getRow() + ':F' + cel.getRow());
      plage.copyTo(archive.getRange('A' + 2), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false); 
      feuille.deleteRow(cel.getRow());
    }
  }
}

je n'ai pas testé ...

@Mike

"merci Gilbert ... mais in fine cela marche quand même ?"

euh non chez moi !!! il faut spécifier si la cellule est true ou false ce qui me paraît normal !!!!

Merci beaucoup pour votre aide.

Ca fonctionne parfaitement.

Rechercher des sujets similaires à "script archivage"