IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

POWER Discussion :

Power Query - Supprimer dans une col le texte d'une autre colonne en case insensitive


Sujet :

POWER

  1. #1
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    1 026
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 1 026
    Billets dans le blog
    45
    Par défaut Power Query - Supprimer dans une col le texte d'une autre colonne en case insensitive
    Bonjour

    J'ai les données ci-dessous dans la table Table1 dont les données ont été chargées depuis une page web

    Nom Acronyme Volume Circulating Supply
    RONRonin RON $51,814,419ron 46,960,396 619,389,699 RON
    StarknetsTRK STRK $119,283,792457,024,943 strk 2,582,076,158 STRK
    Curve DAO crvToken CRV $303,281,064578,587Crv,068 1,278,297,461 CRV

    Et pour chaque ligne, je veux supprimer le texte de l'Acroyme dans les colonnes Nom, Volume, Circulating Supply.

    Mais la recherche de valeur de l'Acronyme doit se faire en CASE INSENSITIVE et sans position particulière car la valeur de l'Acroyme peut être tout en minuscule ou avec la 1ère lettre en majuscule.

    J'ai une solution seulement pour les valeurs numériques

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    = Table.ReplaceValue(#"Order col",each [Acronyme],null,
        (x,y,z) as text=>
            Text.Trim(Text.Select(x, {"1".."9"} )),
        {"Volume","Circulating Supply"}
    )
    Merci par avance

  2. #2
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 276
    Par défaut
    Bonjour
    il suffit d'ajouter "," et " " à la liste {"1".."9"} pour conserver également les virgules et les espaces : {"1".."9",","," "}.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    = Table.ReplaceValue(Source,each [Acronyme],null,
        (x,y,z) as text=>
            Text.Trim(Text.Select(x, {"1".."9",","," "} )),
        {"Volume","Circulating Supply"}
    )
    Sinon passez le texte en majuscule avant de remplacer l'acronyme (qui est en majuscule) par rien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    = Table.ReplaceValue(Source,each [Acronyme],null,
        (x,y,z) as text=>
            Text.Replace(Text.Upper(x), y, ""),
        {"Volume","Circulating Supply"}
    )
    Stéphane

  3. #3
    Membre éclairé
    Homme Profil pro
    curieux
    Inscrit en
    Février 2025
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations professionnelles :
    Activité : curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2025
    Messages : 37
    Par défaut
    Bonjour à tous,

    Le problème c'est qu'en mettant le texte en majuscules on perd le formatage de la colonne [Nom] en appliquant cette méthode. Il faudrait ensuite reparcourir la chaine et comparer caractère par caractère s'il était en minuscules ou non avant la modification. Ce qui est encore plus ennuyant si on prend le cas de " Curve DAO crvToken" qui devient " CURVE DAO TOKEN" et donc les derniers caractères sont décalés.

    Après bon, c'est bien plus simple de passer le texte en majuscules/minuscules. Ca m'a l'air d'être un vrai casse-tête pour garder le texte original, je n'arrive pas à trouver de solution PQ (en VBA ça se ferait assez bien).

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    1 026
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 1 026
    Billets dans le blog
    45
    Par défaut
    Merci Raccourcix pour avoir complété ma solution.



    Mais ma demande est de pouvoir AUSSI traiter la colonne [Nom]

    La solution indiquée n'est que pour les valeurs numeriques



    NB: Pour le typage j'ai ce script


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    = Table.TransformColumnTypes(
    #"Clean capitalisation",
    {	{"PrixUnitaire", type number},
    	{"Capitalisation", type number} ,
        {"Volume", type number},
        {"Change", type number},
        {"Circulating Supply", type number}
    }
    , "en-US")

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    1 026
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 1 026
    Billets dans le blog
    45
    Par défaut
    Citation Envoyé par sabot'age Voir le message
    Bonjour à tous,

    Le problème c'est qu'en mettant le texte en majuscules on perd le formatage de la colonne [Nom] en appliquant cette méthode. Il faudrait ensuite reparcourir la chaine et comparer caractère par caractère s'il était en minuscules ou non avant la modification. Ce qui est encore plus ennuyant si on prend le cas de " Curve DAO crvToken" qui devient " CURVE DAO TOKEN" et donc les derniers caractères sont décalés.....
    C'est le problème de cette solution

  6. #6
    Membre éclairé
    Homme Profil pro
    curieux
    Inscrit en
    Février 2025
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations professionnelles :
    Activité : curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2025
    Messages : 37
    Par défaut
    Citation Envoyé par informer Voir le message
    Merci Raccourcix pour avoir complété ma solution.

    Mais ma demande est de pouvoir AUSSI traiter la colonne [Nom]
    Ajoutez la colonne dans la liste à traiter, je crois que @raccourcix l'a oubliée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    = Table.ReplaceValue(Source,each [Acronyme],null,
        (x,y,z) as text=>
            Text.Replace(Text.Upper(x), y, ""),
        {"Nom","Volume","Circulating Supply"}
    )
    Bonne journée

  7. #7
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    1 026
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 1 026
    Billets dans le blog
    45
    Par défaut
    Citation Envoyé par sabot'age Voir le message
    Ajoutez la colonne dans la liste à traiter, je crois que @raccourcix l'a oubliée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    = Table.ReplaceValue(Source,each [Acronyme],null,
        (x,y,z) as text=>
            Text.Replace(Text.Upper(x), y, ""),
        {"Nom","Volume","Circulating Supply"}
    )
    Bonne journée
    Mais comme évoqué, le texte de Nom passe en MAJUSCULE et modifie donc la donnée d'origine

  8. #8
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 276
    Par défaut
    Il suffit de reprendre l'idée du Text.RemoveRange évoqué dans mon précédent post https://www.developpez.net/forums/d2.../#post12067861 avec celle du Text.Upper en ajoutant un Text.PositionOf

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    = Table.ReplaceValue(
      Source, 
      each [Acronyme], 
      null, 
      (x,y,z) => Text.RemoveRange(x, Text.PositionOf(Text.Upper(x), y), Text.Length(y)),
      {"Nom", "Volume", "Circulating Supply"})
    Stéphane

  9. #9
    Membre éclairé
    Homme Profil pro
    curieux
    Inscrit en
    Février 2025
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations professionnelles :
    Activité : curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2025
    Messages : 37
    Par défaut
    Re,
    J'ai écris la fonction suivante qui remplace toutes les occurences du texte Searched dans le texte Source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    let
        RemoveAny = (Source as text, Searched as text) as text =>
            let
                positions = Text.PositionOf(Source, Searched, Occurrence.All, Comparer.OrdinalIgnoreCase),
                indexes = {1 .. List.Count(positions) - 1},
                positions2 = List.InsertRange(
                    List.Transform(indexes, (indx) => positions{indx} - (indx * Text.Length(Searched))),
                    0, {positions{0}}
                ),
                concat = if List.Count(positions2) > 1
                    then
                        List.Accumulate(positions2, Source, (state, current) => Text.ReplaceRange(state, current, Text.Length(Searched), ""))
                    else
                        Text.ReplaceRange(Source, positions{0}, Text.Length(Searched), "")
            in concat
    in
        RemoveAny
    Il suffit de l'invoquer sur les colonnes du tableau en question, avec comme 1e argument la colonne, et second la colonne des acronymes.
    EDIT : je viens de voir la réponse de stéphane, beaucoup plus simple (s'il n'y a qu'une occurence à remplacer par cellule)

  10. #10
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 276
    Par défaut
    En effet,

    pour retirer toutes les occurrences directement il faut un List.Accumulate. j'utilise un List.Reverse pour partir de la fin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    = Table.ReplaceValue(
     Source, 
     each [Acronyme], 
     null, 
     (x,y,z) => 
        List.Accumulate(
          List.Reverse(Text.PositionOf(x, y, Occurrence.All, Comparer.OrdinalIgnoreCase)),
          x, 
          (s,c)=>Text.RemoveRange(s, c, Text.Length(y))),
     {"Nom", "Volume", "Circulating Supply"})
    Stéphane

  11. #11
    Membre éclairé
    Homme Profil pro
    curieux
    Inscrit en
    Février 2025
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Italie

    Informations professionnelles :
    Activité : curieux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Février 2025
    Messages : 37
    Par défaut
    Wow super @Raccourcix
    C'est malin de partir à l'envers, moi qui me suit embeté avec une liste d'indices à décaler… Bon je débute sur PQ, on dira que ça explique mon attrait à faire compliqué quand il y a simple et élégant

    Bonne journée à tous, il me semble que le problème est résolu avec cette dernière fonction.

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    1 026
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 1 026
    Billets dans le blog
    45
    Par défaut
    Raccourcix,

    Mes connaissances sur le langage M sont toutes nouvelles, j'ai besoin d'une validation de ce que j'en ai compris


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Table.ReplaceValue(param1, param2, param3, param4)
    param4 = liste des colonnes à traiter => boucle sur le param4 ici  {"Nom", "Volume", "Circulating Supply"}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     each [Acronyme] permet d'initier comme un curseur qui pointe ligne par ligne tout ça dans une boucle sur le param4

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Text.PositionOf(x, y, Occurrence.All, Comparer.OrdinalIgnoreCase) = liste de la position de chaque item correspondant à l'Acronyme pour la ligne pointée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List.Accumulate (x,y,z) => Pour chaque ligne pointée passage en paramètre de 
    x =  colonnes courante de la liste {"Nom", "Volume", "Circulating Supply"}  de la ligne pointée ???  => Si c'est le cas je ne comprend pas pourquoi ?
    y = donnée de la colonne [Acronyme] de la ligne pointée ???
    z = null ???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    (s,c)=>Text.RemoveRange(s, c, Text.Length(y)))
    s = Valeur de la liste ext.PositionOf
    c = x = donnée de la colonne courante de la liste {"Nom", "Volume", "Circulating Supply"}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List.Accumulate (list, colonne
          (s,c)=>Text.RemoveRange(s, c, Text.Length(y))) => concatène le résultat précédent de la fonction Text.RemoveRange au résultat courant de la fonction Text.RemoveRange
    Les explications sont surement approximatives mais j'espère qu'elles se tiennent

  13. #13
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 276
    Par défaut
    Bonjour
    je n'ai pas trop le temps ce matin de rentrer dans le détail des fonctions Table.ReplaceValue et List.Accumulate
    notez qu'il y a 5 arguments dans Table.ReplaceValue

    de base dans un Table.ReplaceValue on a 3 premier arguments : la valeur de chacune des colonnes du 5e argument (le x), la valeur à remplacer (le y) et la nouvelle valeur (le z) mais on est libre d'utiliser les 2e et 3e arguments comme on le souhaite (on travaille sur un enregistrement = une ligne)

    dans mon cas, le 3e argument "z" ne sert pas ensuite dans la fonction de remplacement (qui est en 4e argument) donc j'ai mis null

    dans List.Accumulate, s,c = "state" et "current" , pour supprimer successivement avec Table.RemoveRange toutes les occurrences de l'Acronyme dans le texte initial.
    dans Excel, on retrouve cette fonction List.Accumulate avec REDUCE


    les explications des fonctions sur le site Microsoft sont souvent restreintes
    en complément, voici quelques liens vers le site de Rick de Groot (une de mes sources d'apprentissage sur Power Query)
    https://gorilla.bi/power-query/replace-values/
    https://gorilla.bi/power-query/list-accumulate/
    https://gorilla.bi/power-query/repla...le-substrings/

    Stéphane

  14. #14
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : ingénieur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2015
    Messages : 1 276
    Par défaut
    Une dernière précision
    dans les 2e et 3e argument (y et z), on travaille sur l'enregistrement en cours (la ligne) mais Power Query ne connait pas la colonne du 5eme argument qui est actuellement traitée (le x)
    La conséquence est que dans ces 2 arguments on ne peut pas faire référence à la colonne actuelle (qui n'est disponible que dans le x)


    Pas de problème par contre si si on ne devait remplacer l'acronyme que dans une seule colonne


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    = Table.ReplaceValue(
     Source, 
     each Text.Length([Acronyme]), 
     each  List.Reverse(Text.PositionOf([Nom], [Acronyme], Occurrence.All, Comparer.OrdinalIgnoreCase)), 
     (x,y,z) => List.Accumulate(z, x, (s,c)=>Text.RemoveRange(s, c, y)),
     {"Nom"})
    Stéphane

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/02/2023, 15h29
  2. Réponses: 10
    Dernier message: 28/06/2022, 21h20
  3. [XL-365] Power Query - Extraction dans une nouvelle colonne
    Par Philippe Tulliez dans le forum Conception
    Réponses: 5
    Dernier message: 16/03/2021, 20h38
  4. Réponses: 8
    Dernier message: 15/01/2019, 10h57
  5. Réponses: 2
    Dernier message: 26/07/2006, 10h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo