Masquer une ligne en fonction d'un critère

Bonjour,

J'ai récupéré ce code sur le sujet suivant mais il ne fonctionne pas.

Je suis parti avant de l'adapter à mes besoins de l'exemple.

https://forum.excel-pratique.com/sheets/masquer-une-ligne-en-fonction-d-un-critere-155569

Quelqu'un pourrait éventuellement m'éclairer sur le sujet.

function transfert(){ 
  var feuille = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var r = SpreadsheetApp.getActiveSpreadsheet().getActiveRange();
  if (r.getColumn() == 7 && feuille.getName() == 'Actif'){ 
    if(r.getValue() == 'OUI'){ 
      var destination = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
      destination.insertRowBefore(2);
      var plage = feuille.getRange('A' + r.getRow() + ':G' +  r.getRow()); 
      plage.copyTo(destination.getRange('A2'), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);  
      Browser.msgBox("Ligne " + r.getRow() + " archivée !");
      feuille.deleteRow(r.getRow());
    }
  } 
  if (r.getColumn() == 7 && feuille.getName() == 'Archive'){ 
    if(r.getValue() != 'OUI'){ 
      var destination = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Actif");
      destination.insertRowBefore(2);
      var plage = feuille.getRange('A' + r.getRow() + ':G' +  r.getRow()); 
      plage.copyTo(destination.getRange('A4'), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);  
      Browser.msgBox("Ligne " + r.getRow() + " ré-activée !");
      feuille.deleteRow(r.getRow());
    }
  }
}

Merci

Bonjour,

La fonction filter ne répondrait-elle pas à vos besoins ?

J'aimerais vraiment pouvoir appliquer cette fonction plus poussée.

Bizarrement, parfois elle fonctionne uniquement sur la ligne 4 mais cela reste très aléatoire.

Bonjour,

J'ai de côté un code permettant de masque des colonnes, il suffit d'adapter avec des lignes + il se lance à chaque modification, si vous voulez qu'il se lance en fonction d'un critère, quel est-il ?

function onEdit() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange(" plage des cases à cocher ");
  var values = range.getValues();
  var plage = [[0,0],[0,0],[0,0],[0,0],[0,0]] // coordonnées des colones à afficher / masquer
  for (var i=0; i<values.length;i++) {
    if (values[i][0]==true){sheet.showColumns(plage[i][0],plage[i][1])}
    else {sheet.hideColumns(plage[i][0],plage[i][1])}
  }
}

L'intérêt du script que j'ai mis en exemple, c'est qu'il copie les lignes qui correspondent au critère sélectionné dans un autre onglet pour ne laisser dans l'onglet principal que les lignes qui ne correspondent pas. Sauf que le script s'exécute correctement mais ne fonctionne pas complètement.

qu'il copie les lignes qui correspondent au critère sélectionné dans un autre onglet pour ne laisser dans l'onglet principal que les lignes qui ne correspondent pas.

Quel est ce critère ?

Le critère est si en Colonne XX, la case est cochée, la ligne est copiée dans l'onglet ARCHIVE et supprimée de l'onglet ACTIF.

Dans l'exemple du lien, la critère est si en colonne G = "OUI", la ligne est copiée dans l'onglet ARCHIVE et supprimée de l'onglet ACTIF

Bonjour,

Donc votre but n'est pas de "masquer une ligne en fonction d'un critère" mais, lorsque dans votre tableau une ligne est cochée, elle est coupée de l'onglet avec et collée dans l'onglet archive ?

Si c'est ce que vous voulez faire, à partir de votre fonction :

function transfert(){ 
  cosnt activSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const archivSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FEUILLE ARCHIVE"); // à changer si necessaire
  var r = activSheet.getRange('A1:Z200').getValues(); // ici mettez la plage de votre tableau
  for (i=0;i<r.lenght;i++){
      if (r.getColumn() == 7 && r[?] == 'OUI'){  // mettez le numéro de colonne correspondant à votre oui / non à la place du ?
         atchivSheet.appendRow(r[i]);
         Browser.msgBox("Ligne " + r[i] + " archivée !");
         activSheet.deleteRow(r[i]);
    }
  }

Voyez déjà si ça fonctionne, si OK vous avez juste à inverser la condition et les plages pour revenir dans votre feuille active.

Bonjour Pierre,

J'ai testé votre proposition mais elle ne fonctionne pas.

Ci-joint le lien si vous pouvez regarder.

https://docs.google.com/spreadsheets/d/1_eBofRQdDCwXG9_IW8V5gilwLH9THD0Ng3OpMA55D_M/edit?usp=sharing

Bonjour,

Voici un code fonctionnel :

function transfert() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const activSheet = ss.getSheetByName("Actif");
  const archivSheet = ss.getSheetByName("Archive");
  var activData = activSheet.getDataRange().getValues();
  var archivData = archivSheet.getDataRange().getValues();
  const nbLigneEnTete = 1;     

  for (var i = activData.length - nbLigneEnTete; i >= 0; i--) {
    if (activData[i][6] === 'OUI') {
      archivSheet.appendRow(activData[i]);
      activSheet.deleteRow(i + 1);}}

  for (var j = archivData.length - nbLigneEnTete; j >= 0; j--) {
    if (archivData[j][6] === 'NON') {
      activSheet.appendRow(archivData[j]);
      archivSheet.deleteRow(j + 1);}}
}

Voici l'explicaiton étape par étape

1- on déclare les variables, constantes :

Le fichier et les 2 feuilles

const ss = SpreadsheetApp.getActiveSpreadsheet();
  const activSheet = ss.getSheetByName("Actif");
  const archivSheet = ss.getSheetByName("Archive")

Les 2 plages de données et le nombre de lignes d'en tête :

  var activData = activSheet.getDataRange().getValues();
  var archivData = archivSheet.getDataRange().getValues();
  const nbLigneEnTete = 1;

2- Première boucle, qui dure le nombre de données présente dans la feuille active - ligne d'en-tête

  for (var i = activData.length - nbLigneEnTete; i >= 0; i--) {

on vérifie si en position 6 il est indiqué OUI (c'est en colonne 7, mais on commence à 0)

    if (activData[i][6] === 'OUI') {

Si oui, on insere dans la feuille archive la ligne, puis, on la supprime de la feuille active :

      archivSheet.appendRow(activData[i]);
      activSheet.deleteRow(i + 1);}}

3- IDEM dans la feuille archive mais avec NON et les feuilles inversées :

  for (var j = archivData.length - nbLigneEnTete; j >= 0; j--) {
    if (archivData[j][6] === 'NON') {
      activSheet.appendRow(archivData[j]);
      archivSheet.deleteRow(j + 1);}}

Merci beaucoup Pierre pour toutes ses explications.

Ca fonctionne parfaitement, je vais essayer de l'adapter à mon fichier définitif.

Je ne comprends pas trop l'étape 3

3- IDEM dans la feuille archive mais avec NON et les feuilles inversées :

Dans le 1er cas :

On est dans le fichier actif.

On vérifie si la donnée à l'emplacement 6 = OUI

Si vrai, on insère la ligne dans le fichier archive

Puis on supprime la ligne dans actif.

3- IDEM dans la feuille archive mais avec NON et les feuilles inversées :

> signifie que le code est très similaire, on inverse juste les conditions :

On est dans le fichier archive.

On vérifie si la donnée à l'emplacement 6 = NON

Si vrai, on insère la ligne dans le fichier actif

Puis on supprime la ligne dans archive.

Merci vraiment d'avoir pris le temps de me créer et m'expliquer ce script.

La Partie 3 est elle forcément nécessaire ?

Tout dépend de votre usage, je me suis basé sur votre script initial qui prévoyait ce cas, maintenant si, une fois archivé, vos lignes ne vont plus bouger en effet ce n'est pas utile.

Bonjour,

Ce script fonctionne parfaitement.

Je souhaiterais savoir s'il est possible de ne copier qu'une partie de ligne et non la ligne complète ?

Exemple de la Colonne A à la Colonne E

Bonjour,

Bien sûr, dans ce cas vous pouvez ou bien changer la range sur laquelle on travaille, ne plus prendre toute la page mais juste les premières colonnes :

  var activData = activSheet.getRange(1,1,activSheet.getLastRow(),5).getValues();
  var archivData = archivSheet.getDataRange(1,1,activSheet.getLastRow(),5).getValues();
  

Ou bien utiliser slice pour couper les éléments à transférer :

  for (var i = activData.length - nbLigneEnTete; i >= 0; i--) {
    if (activData[i][6] === 'OUI') {
      archivSheet.appendRow(activData[i].slice(0, 5));
      activSheet.deleteRow(i + 1);}}

Parfait, la première solution génère une erreur mais la seconde fonctionne parfaitement.

Merci beaucoup ...

Rechercher des sujets similaires à "masquer ligne fonction critere"