Apps Script : script à partir d'un query

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 ?

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