Page 1 sur 1

script à partir d'un query

Publié : 31 oct. 2023 15:55
par TheZig
Bonjour,

Dans un onglet nommé Donnees, 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, il y a un id unique pour chaque enregistrement.
Dans la colonne P de l'onglet Rapprochement je mets une case à cocher, que je vais cocher pour indiquer que la ligne doit être traitée par ma macro
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;
}

Chaque fois qu'une ligne est traitée, elle n'apparait donc plus dans la liste puisqu'elle ne répond plus aux exigence 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 ?

Édit: je me disais peut-être en mettant le résultat de la boucle dans un tableau, puis, en faisant une autre boucle pour parcourir les lignes du tableau et mettre à jour ma feuille Données en une seule fois avec des setValues ?
Seulement sur ma feuille Données, les lignes à mettre à jour ne seront pas forcément contiguës. Est-ce que ça ne posera pas un problème ?

Re-edit:  mon raisonnement me conduit à penser que je devrais peut-être faire un copier-coller des valeurs filtrées de mon onglet, dans une feuille temporaire puis de l'effacer à la fin ?

Re: script à partir d'un query

Publié : 15 nov. 2023 10:57
par Patrick_Té
Bonjour,

Puisque la formule Query se recalcule au fur et à mesure de l'exécution du script, il suffit de traiter toujours la ligne 2 :

La boucle  for (li=2; li<=lastRowA; li++)   va bien s'exécuter du nombre de lignes à traiter mais dans le scipt il faut remplacer : getRange('A'+li)   par   getRange('A'+2)     et de même pour getRange('P'+li)

Ainsi le script traite toujours la ligne 2 et comme le query recalcule à chaque tour de la boucle : le tableau issu du query se dés-empile au fur et à mesure.

Espérant avoir été clair ...

Bonne journée