Apps Script: macro à partir d'un query

Bonjour,

Dans l'onglet nommé Donnees d'un classeur Google Sheets , j'ai...des données !
Dans un autre onglet que je nomme Rapprochement, je fais un query sur ces données, et notamment je demande les enregistrements dont le contenu de la colonne M est false
(BDD_All est la plage des données de la feuille Donnees):

=query(BDD_All;"select A,B,C,D,E,F,G,H,I,J,K,L,N,O,M where A>0 and M=false";1)

dans la colonne A, j'ai mis un id unique pour chaque enregistrement.
Dans la colonne P de l'onglet Rapprochement je mets des cases à cocher, que je vais cocher pour indiquer que telle ou telle ligne doit être traitée par ma macro.

voici le code que j'ai écrit :

let FeuilRapprochement = classeur.getSheetByName('Rapprochement');

function majRapprochement() {
    //cherche d'abord la dernière ligne non vide de la colonne A
    const Avals = FeuilRapprochement.getRange("A1:A").getValues();
   const lastRowA = Avals.filter(String).length;
Logger.log(lastRowA);
    for (li=2; li<=lastRowA; li++) //parcours des lignes jusqu' à la dernière non vide
     {
     let idMouvmt = FeuilRapprochement.getRange('A'+li).getValue();
     const numeroLigne = trouverMouvementParSonId(idMouvmt); //dans la feuille Données, cherche le n° de ligne où se trouve l'id du mouvement
     if (numeroLigne > 0)
        { //si  le mouvement est trouvé
            let rapproch = FeuilRapprochement.getRange('P'+li).getValue();   //valeur de la case sur la ligne col P de la feuille Rapprochement
            if (rapproch == true)
               { // si la case est sur True
               cellCol = FeuilleDonnees.getRange('M' +numeroLigne); //va sur la cellule col M de la feuille Données pour cocher la case
               rapprochActuels = cellCol.getValue();
               cellCol.setValue(rapproch);
              FeuilleDonnees.getRange('O' +numeroLigne).setValue(new Date()); //on met la date de modif
             // FeuilRapprochement.getRange(li,16).setValue(false);   //j'ai désactivé ça mais ça ne change rien au résultat sauf une case décochée
             }
       }
   }
}

dans cette macro j'en utilise une autre dont voici le code:

function trouverMouvementParSonId(Id){
//on va chercher le numéro de ligne où se trouve l'id de l'objet Mouvement
let data = FeuilleDonnees.getDataRange().getValues();
let trouverIndex = data.findIndex(Mouvement => Mouvement[0] == Id);

return ++trouverIndex;
}

Ça fonctionne, sauf que je n'avais pas pensé à une chose : Chaque fois qu'une ligne est traitée, elle n'apparait donc plus dans la liste puisqu'elle ne répond plus aux exigences du query.
Le problème est que c'est sans doute à cause de cela que la macro ne prend qu'une ligne sur 2 et donc au final, seule la moitié des lignes cochées est traitée...

A votre avis, quel est le moyen d'arranger cela ?

lien vers mon classeur:

https://docs.google.com/spreadsheets/d/1kloNwGiOM5iHkJQI-Kxm7nhIDG1SpBF_1gDsQPRDNDs/edit?usp=drivesd...

Edit:

En attendant mieux (peut-être), à partir de là feuille qui a le query, je fais un getValues, puis un setValues , (bref un copié collé en quelque sorte) sur une feuille temporaire, afin de transformer les données dynamiques en données statiques....et quand j'ai fini de travailler dessus, j'efface la feuille temporaire

Bonjour,

Une piste en passant

Le problème est que c'est sans doute à cause de cela que la macro ne prend qu'une ligne sur 2 et donc au final, seule la moitié des lignes cochées est traitée...

En général pour ce type de problème, une solution simple consiste à commencer la boucle en partant de la fin (par exemple avec une boucle for qui va du dernier au premier, et avec i--). De cette manière, même si la ligne est ensuite retirée, ça ne pose plus de problème.

Cordialement,

Merci Sébastien pour cette réponse, je ne pense jamais à utiliser le i- - au lieu du i++

Entre temps, j'ai trouvé ma solution et voici la macro qui, à présent, fonctionne. Si ça peut en aider d'autres...

function  majRapprochement() {

  const derLi = FeuilRapprochement.getLastRow()-1
  const dataP = FeuilRapprochement.getRange(2,1,derLi,14).getValues();
//filtrage du tableau des données qui ne retient que les lignes où la case de la colonne M est cochées
  const dataTrue = dataP.filter(dataRow=>dataRow[13]===true)
//boucle sur le tableau
  for (li=0; li<dataTrue.length; li++) 
    {
    const idMouvmt = dataTrue[li][0]

    const numeroLigne = trouverMouvementParSonId(idMouvmt);
        if (numeroLigne > 0)
        { //si on trouve le Mouvement
//on va sur la cellule de la col. K de la feuille Données afin de cocher la case 
        FeuilleDonnees.getRange('K' +numeroLigne).setValue(true); 
//on met la date de modif en col M       
        FeuilleDonnees.getRange('M' +numeroLigne).setValue(new Date()); 
        }
    }
  FeuilRapprochement.getRange('A3:N').clear();
  FeuilRapprochement.getRange('N3:N').clearDataValidations();

}
Rechercher des sujets similaires à "apps script macro partir query"