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 - Table.TransformColumn à une liste dynamique de colonnes


Sujet :

POWER

  1. #1
    Membre éclairé Avatar de Le Sage
    Homme Profil pro
    Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Inscrit en
    Novembre 2009
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2009
    Messages : 218
    Par défaut Power Query - Table.TransformColumn à une liste dynamique de colonnes
    Bonjour à toutes et tous !

    Je cherche à appliquer Table.TransformColumn à une liste dynamique de colonnes, mais je butte...


    Ca donnerait quelque-chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    let fxNettoyerToutes = (Table) =>    let
            Colonnes = Table.ColumnsOfType(Table, {type nullable text}),
            Netoyage = Table.TransformColumns(Table, {{Colonnes, Text.Clean, type text}})
            Resultat = Table.TransformColumns(Netoyage, {{Colonnes, Text.Trim, type text}})
        in
            Resultat
    in
        fxNettoyerToutes

    Merci d'avance de pour vos réponses.

  2. #2
    Membre éclairé Avatar de Le Sage
    Homme Profil pro
    Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Inscrit en
    Novembre 2009
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2009
    Messages : 218
    Par défaut
    Ayant fini par pondre la solution, je vous la propose ci-dessous, histoire d'éviter à d'autre de se casser la tête pendant des heures :

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    let fxNettoyerToutes = (Table) =>    
        let
            ColonnesTexte = Table.FromList(
                                Table.ColumnsOfType(
                                        Table
                                        , {type nullable text}
                                        )
                                , Splitter.SplitByNothing()
                                , null
                                , null
                                , ExtraValues.Ignore
                                ),
     
     
            AjoutTextClean = Table.AddColumn(
                                ColonnesTexte
                                , "Clean"
                                , each Text.Clean
                                , Function.Type
                                ),
     
     
            AjoutTextTrim = Table.AddColumn(
                                ColonnesTexte
                                , "Trim"
                                , each Text.Trim
                                , Function.Type
                                ),
     
     
            Clean = Table.TransformColumns(
                            Table
                            , List.Zip({ColonnesTexte[Column1], AjoutTextClean[Clean]})
                            , null
                            , MissingField.Ignore
                            ),
     
     
            Trim = Table.TransformColumns(
                            Clean
                            , List.Zip({ColonnesTexte[Column1], AjoutTextTrim[Trim]})
                            , null
                            , MissingField.Ignore
                            )
        in
            Trim
    in
        fxNettoyerToutes

    Si vous avez mieux, n'hésitez pas à participer

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 735
    Par défaut
    Bonsoir,

    Je n'ai pas bien compris si tu voulais pouvoir choisir en argument la liste de colonnes à traiter donc voici deux versions différentes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    let
      Source = (table as table, ColumnsList as list) =>
        Table.TransformColumns(
          table, 
          List.Transform(ColumnsList, each {_, each Text.Trim(Text.Clean(_)), type nullable text})
        )
    in
      Source

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let
      Source = (table as table) =>
        Table.TransformColumns(
          table, 
          List.Transform(
            Table.ColumnsOfType(table, {type nullable text}), 
            each {_, each Text.Trim(Text.Clean(_)), 
            type nullable text}
          )
        )
    in
      Source

  4. #4
    Membre éclairé Avatar de Le Sage
    Homme Profil pro
    Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Inscrit en
    Novembre 2009
    Messages
    218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Formateur Conseil en Bureautique et CMS, Développeur VBA, Power Query, Power Pivot
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2009
    Messages : 218
    Par défaut
    Bonjour Promethee25, et merci pour ton retour.

    J'ai encore du mal avec ce foutu _, mais lorsque je lis ton code, j'ai l'impression que ce sont les noms de colonnes qui sont modifiés, et pas le contenu des colonnes...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let  Source = (table as table, ColumnsList as list) =>
        Table.TransformColumns(
          table, 
          List.Transform(ColumnsList, each {_, each Text.Trim(Text.Clean(_)), type nullable text})
        )
    in   Source
    Je traduis : List.Transform(ColumnsList, each {Elément de ColumnList, each Text.Trim(Text.Clean(Elément "trimé" de ColumnList)), type nullable text})

    Du coup, et par extension, dans le deuxième code ce serait le nom des colonnes de type texte qui serait traité, et non le contenu de ces colonnes tel qu'effectué dans mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            Clean = Table.TransformColumns(
                            Table
                            , List.Zip({ColonnesTexte[Column1], AjoutTextClean[Clean]})
                            , null
                            , MissingField.Ignore
                            ),
    où List.Zip({ColonnesTexte[Column1], AjoutTextClean[Clean]})
    donne {{Nom de la Colonne, Text.Clean}, {Nom de la Colonne, Text.Clean}}

    Est-ce que je me trompe dans mon interprétation, et le cas échéant, comment l'éviter à l'avenir ?

    Edit : Après essai en remplaçant Text.Clean par Text.Upper dans nos deux versions pour que ce soit plus visible, j'obtiens bien la transformation dans toutes mes colonnes texte avec mon code et aucune différence ni dans les titres ni dans le contenu avec la tienne, ce qui tend à conforter mon impression.

    Merci d'avance de ton retour

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 735
    Par défaut
    Bonjour,

    "_" représente l'élément pointé par each, qui dépend du contexte comme tu sembles l'avoir compris. Mais ton interprétation ne me semble pas parfaitement exacte.

    Dans le code que j'ai proposé:
    • Le premier each (et ainsi le "_" qui suit) représente bien successivement chaque élément de ColumnList (car List.Transform applique la fonction définie en second argument à chaque élément de la liste définie en premier argument). Il s'agit des noms de colonnes, c'est-à-dire des éléments de type text ("Colonne1", "Colonne2", etc).
    • La portée du second each est dictée par le prototype de la fonction Table.TransformColumns:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Table.TransformColumns(tableATransformer, ListeDesTransformations)
      où chaque élément de la ListeDesTransformations est lui-même une liste ayant pour prototype
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      {NomDeLaColonneATransformer, FonctionAAppliquerAChaqueElémentDeLaColonneATransformer, TypeOptionnel}
      Le second each (et ainsi le "_" qui suit) correspond à la FonctionAAppliquerAChaqueElémentDeLaColonneATransformer; il représente donc successivement chaque élément de la colonne à traiter (on pourrait dire chaque case/cellule de la colonne).


    En gros, s'il y a "Colonne1", "Colonne2", ... dans la liste des colonnes à traiter, je crée la ListeDesTransformations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {{"Colonne1", each Text.Trim(Text.Clean(_)), type nullable text}, {"Colonne2", each Text.Trim(Text.Clean(_)), type nullable text}, , {..., each Text.Trim(Text.Clean(_)), type nullable text}}
    avec l'aide de List.Transform et cela va donc nettoyer chaque élément des colonnes citées.

    Les boucles n'existent pas en l'état dans Power Query mais:
    • List.Transform permet de faire l'équivalent d'une boucle For non récursive
    • List.Accumulate permet de faire l'équivalent d'une boucle For récursive
    • List.Generate permet de faire l'équivalent d'une boucle While


    Concernant Text.Upper: si tu inclus ça dans le code que j'ai proposé, ça va bien mettre en majuscules le contenu des colonnes visées, comme n'importe quelle autre traitement que tu ajouterais (testé ok chez moi):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let  Source = (table as table, ColumnsList as list) =>
        Table.TransformColumns(
          table, 
          List.Transform(ColumnsList, each {_, each Text.Upper(Text.Trim(Text.Clean(_))), type nullable text})
        )
    in   Source

    Avec ton List.Zip, tu es passé par des moyens détournés (et complexes) pour arriver au même but; List.Zip permet en quelque sorte de transposer une liste de listes:
    {{1,2}, {3,4}} devient {{1,3}, {2,4}}.

  6. #6
    Membre Expert
    Homme Profil pro
    ingénieur
    Inscrit en
    Mars 2015
    Messages
    1 333
    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 333
    Par défaut
    Bonjour
    Une autre possibilité en utilisant le 3e argument de la fonction Table.TransformColumns : transformation par défaut

    si la colonne est de type text : on applique Text.Trim(Text.Clean(_)) sinon on ne fait aucune modification (avec le _ seul).

    mais c'est peut-être moins efficace à l'exécution car on parcourt toutes les colonnes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     (table as table) =>
        Table.TransformColumns(
            table,
            {},
            each if Value.Type(_)=type text then Text.Trim(Text.Clean(_)) else _
        )
    Stéphane

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    735
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 735
    Par défaut
    Bonjour Raccourcix,

    L'impact sur les performances n'est pas tant à mon sens le nombre de colonnes que le nombre de lignes puisque la fonction "each ..." est appliquée à chaque case des colonnes à traiter donc le test "if Value.Type(_)=type text" s'appliquera à chaque case de toutes les colonnes (d'où l'impact majeur du nombre de lignes qui est en général bien plus élevé que le nombre de colonnes).

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 28/06/2022, 22h20
  2. afficher les contenu d'une liste dynamiquement
    Par mzt.insat dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 06/04/2006, 19h02
  3. Réponses: 3
    Dernier message: 22/03/2006, 18h24
  4. Réponses: 1
    Dernier message: 16/01/2006, 18h36
  5. Réponses: 2
    Dernier message: 27/12/2005, 21h09

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