Power Query Faire un traitement sur une colonne à partir d'une autre liste

btil

XLDnaute Nouveau
Bonjour,

je viens de découvrir les List.Accumulate, via l'article : https://excel-downloads.com/threads...-avec-list-accumulate.20080604/#post-20625927

En revanche, j'ai un cas particulier et je n'arrive pas à trouver la bonne formule,
j'en ai une qui fonctionne mais qui n'est pas optimisée et ralentie le traitement, le sens de la boucle n'est pas bon :

j'ai une extraction (plusieurs milliers de lignes) dans un fichier texte qui contient des stocks de produits & dans une des colonnes, j'ai un nom d'emplacement.

Dans les emplacements, il y a le nom de la ville ou son code postal, malheureusement pr moi, il y a d'autres informations dans les libellés d'emplacement (info sur l'emplacement et/ou le format du produit) et il y a bien un standard mais différent pour chaque type d'emplacement, ce qui fait que je ne peux pas décomposer les données facilement :

ex :
Temp-Paris-BB
Temp-Paris-SAC
DECLASSE59000
RETOUR75000
Vente-BB2-Lille

je lit cette extraction avec Power Query dans Excel et en améliore l'affichage.

j'ai voulu nettoyer les emplacements pour avoir les villes au propre :
PowerQuery:
=Table.ReplaceValue(#"étape précédente","Temp-","",Replacer.ReplaceText,{"Ville"})
qui marche très rapidement sur tous les emplacements en une fois, sauf qu'il faut que je le fasse avec une trentaine de chaîne et il est possible que je doive en ajouter d'autre dans le futur !

je me suis donc dit que je pourrais mettre tte ses chaines ("Temp", "BB", ..) à supprimer dans une table à part :
NettoyageEmplacement[Find]

j'ai trouvé cette formule :
PowerQuery:
= Table.AddColumn(#"étape précédente", "Ville", each List.Accumulate(
   List.Numbers(0, Table.RowCount(NettoyageEmplacement)),
   [Emplacement],
   (A,B) => Text.Replace(A, NettoyageEmplacement[Find]{B},"")))

Sauf que pour moi, le List.Accumulate, travaille sur chaque ligne d'emplacement, une par une, ce qui ralenti le traitement.

j'ai testé de faire un mélange des deux en dupliquant la colonne et en essayant de faire le replacer en boucle sur tte les chaines à supprimer, mais ça tombe en erreur :

PowerQuery:
= List.Accumulate(NettoyageEmplacement[Find],"",
(state,current)=> Table.ReplaceValue(#"étape précédente",{current},"",Replacer.ReplaceText,{"Ville"}))

quelqu'un aurait une piste ?
 
Solution
Bonjour btil, oguruma, le forum,

Tu peux tester avec ce code :
PowerQuery:
= List.Accumulate(NettoyageEmplacement[Find], #"étape précédente", (state, current) => Table.ReplaceValue(state, current, "", Replacer.ReplaceText, {"Ville"}))

A+

oguruma

XLDnaute Occasionnel
Bonjour,

je viens de découvrir les List.Accumulate, via l'article : https://excel-downloads.com/threads...-avec-list-accumulate.20080604/#post-20625927

En revanche, j'ai un cas particulier et je n'arrive pas à trouver la bonne formule,
j'en ai une qui fonctionne mais qui n'est pas optimisée et ralentie le traitement, le sens de la boucle n'est pas bon :

j'ai une extraction (plusieurs milliers de lignes) dans un fichier texte qui contient des stocks de produits & dans une des colonnes, j'ai un nom d'emplacement.

Dans les emplacements, il y a le nom de la ville ou son code postal, malheureusement pr moi, il y a d'autres informations dans les libellés d'emplacement (info sur l'emplacement et/ou le format du produit) et il y a bien un standard mais différent pour chaque type d'emplacement, ce qui fait que je ne peux pas décomposer les données facilement :

ex :
Temp-Paris-BB
Temp-Paris-SAC
DECLASSE59000
RETOUR75000
Vente-BB2-Lille

je lit cette extraction avec Power Query dans Excel et en améliore l'affichage.

j'ai voulu nettoyer les emplacements pour avoir les villes au propre :
PowerQuery:
=Table.ReplaceValue(#"étape précédente","Temp-","",Replacer.ReplaceText,{"Ville"})
qui marche très rapidement sur tous les emplacements en une fois, sauf qu'il faut que je le fasse avec une trentaine de chaîne et il est possible que je doive en ajouter d'autre dans le futur !

je me suis donc dit que je pourrais mettre tte ses chaines ("Temp", "BB", ..) à supprimer dans une table à part :
NettoyageEmplacement[Find]

j'ai trouvé cette formule :
PowerQuery:
= Table.AddColumn(#"étape précédente", "Ville", each List.Accumulate(
   List.Numbers(0, Table.RowCount(NettoyageEmplacement)),
   [Emplacement],
   (A,B) => Text.Replace(A, NettoyageEmplacement[Find]{B},"")))

Sauf que pour moi, le List.Accumulate, travaille sur chaque ligne d'emplacement, une par une, ce qui ralenti le traitement.

j'ai testé de faire un mélange des deux en dupliquant la colonne et en essayant de faire le replacer en boucle sur tte les chaines à supprimer, mais ça tombe en erreur :

PowerQuery:
= List.Accumulate(NettoyageEmplacement[Find],"",
(state,current)=> Table.ReplaceValue(#"étape précédente",{current},"",Replacer.ReplaceText,{"Ville"}))

quelqu'un aurait une piste ?
bjr comme ça à la volée
en effet state est vide au départ et c'est certainement la cause de l'erreur
donc il faut ajouter avant ton table.replacevalue
if state="" then {current} else .... et la suite de ton tablereplace

quand tu regardes mes exemples je fais cette vérification avant de faire mes cumuls
ça vient du fait que dans ta boucle tu initialises state à "" et dans le traitement tu associes du texte et des listes donc le format de données n'est pas compatible et ça doit être l'erreur qui t'est remontée comme quoi pwq ne sait associer du texte à une liste

ou tu peux faire l'init de la boucle à { } pour avoir une liste vide

bon sans fichier joint difficile de donner un diag plus précis
 

oguruma

XLDnaute Occasionnel
bjr comme ça à la volée
en effet state est vide au départ et c'est certainement la cause de l'erreur
donc il faut ajouter avant ton table.replacevalue
if state="" then {current} else .... et la suite de ton tablereplace

quand tu regardes mes exemples je fais cette vérification avant de faire mes cumuls
ça vient du fait que dans ta boucle tu initialises state à "" et dans le traitement tu associes du texte et des listes donc le format de données n'est pas compatible et ça doit être l'erreur qui t'est remontée comme quoi pwq ne sait associer du texte à une liste

ou tu peux faire l'init de la boucle à { } pour avoir une liste vide

bon sans fichier joint difficile de donner un diag plus précis
et selon ta volumétrie tu peux passer par les Buffers et les fonctions associées aux Buffers... mais selon le nbr de lignes à traiter.... tu pourrais aussi le payer en perf..... à tester....

ou encore passer par les fonctions List et List.RemoveMatchingItems avec l'option ComparerIgnoreCase pour ignorer la casse des caractères et dans ce cas tu pourrais te passer du List.Accumulate... piste à creuser aussi

ou List.ReplaceValue

et ta liste de mots à supprimer tu peux par contre la monter dans un buffer ça ne doit pas être si énorme que cela ça serait un minimum de gain supplémentaire à défaut de tout bufferiser
 
Dernière édition:

mromain

XLDnaute Barbatruc
Bonjour btil, oguruma, le forum,

Tu peux tester avec ce code :
PowerQuery:
= List.Accumulate(NettoyageEmplacement[Find], #"étape précédente", (state, current) => Table.ReplaceValue(state, current, "", Replacer.ReplaceText, {"Ville"}))

A+
 

btil

XLDnaute Nouveau
Bonjour à tous,

& merci pour vos retours, j'ai eu une autre urgence data hier & je n'ai pas pu tester les recommandations,
@oguruma en effet, je n'était pas certain de l'initialisation de la liste

@mromain, j'ai testé ta version, parfait, plus d'erreur & ça retourne exactement le résultat que je voulais & super rapidement !

un grand merci !!

@oguruma, pr les buffer, je débute en Power Query, je vois que c'est un langage puissant mais un peu déroutant dans certain cas ... exemple de la bcle ;)
 
Dernière édition:

oguruma

XLDnaute Occasionnel
Bonjour à tous,

& merci pour vos retours, j'ai eu une autre urgence data hier & je n'ai pas pu tester les recommandations,
@oguruma en effet, je n'était pas certain de l'initialisation de la liste

@mromain, j'ai testé ta version, parfait, plus d'erreur & ça retourne exactement le résultat que je voulais & super rapidement !

un grand merci !!

@oguruma, pr les buffer, je débute en Power Query, je vois que c'est un langage puissant mais un peu déroutant dans certain cas ... exemple de la bcle ;)
Bonjour, oui, on est tous passés par là mais après un peu de pratique tu verras que ça reste assez abordable c'est comme les formules sous Excel ;) Imagines si tu devais coder tout cela en assembleur :D :)
 

btil

XLDnaute Nouveau
Bonjour, oui, on est tous passés par là mais après un peu de pratique tu verras que ça reste assez abordable c'est comme les formules sous Excel ;) Imagines si tu devais coder tout cela en assembleur :D :)

oui, oui avec la pratique ça va venir pas de soucis et c'est vrai qu'une majorité des fonctions est dispo sans toucher au code ... dc faut s'y plonger c'est tt !

mais la syntaxe est qd même un peu particulière, ça ressemble pas au VBA, au SQL, ... mais on s'y fait

l'assembleur ... ça me rappel de très vieux cours 🤣