POWERQUERY :: Split dynamique de colonnes avec choix du délimiter de colonnes et du délimiteur d'index des colonnes supplémentaires

oguruma

XLDnaute Occasionnel
L'idée :
A partir de ceci :
1708771427830.png


obtenir ceci et quelque soit le nombre de compétences (donc nbr de colonnes supplémentaires qui seront créées) :
1708771456992.png


Pour cela une petite fonction :
PowerQuery:
//----------------------------------------------------------------------------------------------
// Fonction permettant de splitter n'importe quelle colonne d'une table
// avec choix du séparateur et l'index des champs qui seront créés
// une option de nettoyage des colonnes en fin de traitement est aussi possible (par défaut)
//----------------------------------------------------------------------------------------------

let fnSplitDynamicColumns =(
            pTable                          as any,
            pFieldSplit                     as text,
            optional ppDelim                as text,
            optional ppPrefixIndex          as text,
            optional pCleanUp               as logical

        ) =>      
        let

            Source = if pTable is table then
                        pTable
                        else  Excel.CurrentWorkbook(){[Name=pTable]}[Content],
           
            pDelim= if ppDelim is null then
                       ","
                       else ppDelim,

            pPrefixIndex=if ppPrefixIndex is null then
                            "_"
                            else ppPrefixIndex,

            StrEval="each List.Count(Text.PositionOfAny([" & pFieldSplit  & "],{pDelim},Occurrence.All))",
            EvalListCount=Expression.Evaluate(StrEval,[List.Count=List.Count, Text.PositionOfAny=Text.PositionOfAny, pDelim=pDelim, Occurrence.All=Occurrence.All]),
           
            TableDynamicColumnList =
                List.Transform(
                    {1 ..
                    List.Max(Table.AddColumn(
                        Source,
                        "CustomedField",
                        EvalListCount
                        )[CustomedField]
                    ) + 1
                    },
                    each pFieldSplit & pPrefixIndex & Text.From(_)
                ),
           
            TableSplitColumnDelimiter =
                Table.SplitColumn(
                    Source, pFieldSplit,
                    Splitter.SplitTextByDelimiter(pDelim, QuoteStyle.Csv),
                    TableDynamicColumnList
                ),

            ListColumnNames=Table.ColumnNames(TableSplitColumnDelimiter),

            isTbCleanUp = if pCleanUp is null or pCleanUp = true then
                                let
                                    CleanColumnsTable = Table.TransformColumns(TableSplitColumnDelimiter, List.Transform(ListColumnNames, each {_, Text.Clean, type text} ) ),
                                    TrimColumnsTable = Table.TransformColumns(CleanColumnsTable, List.Transform(ListColumnNames, each {_, Text.Trim, type text} ) )
                                in
                                    TrimColumnsTable
                            else TableSplitColumnDelimiter
           
        in
            isTbCleanUp

in
    fnSplitDynamicColumns

Utilisation
PowerQuery:
let
    t= fnSplitDynamicColumns (
            "TB_DATA",
            "COMPETENCES",
            ",",
            ".",
            null)
in
    t

PowerQuery:
let
    Source = fnSplitDynamicColumns("TB_DATA", "COMPETENCES", null, "#", false)
in
    Source
 

Pièces jointes

  • SplitColumns_V0.004.xlsx
    28.5 KB · Affichages: 3
Dernière édition:

oguruma

XLDnaute Occasionnel
L'idée :
A partir de ceci :
Regarde la pièce jointe 1191493

obtenir ceci et quelque soit le nombre de compétences (donc nbr de colonnes supplémentaires qui seront créées) :
Regarde la pièce jointe 1191494

Pour cela une petite fonction :
PowerQuery:
//----------------------------------------------------------------------------------------------
// Fonction permettant de splitter n'importe quelle colonne d'une table
// avec choix du séparateur et l'index des champs qui seront créés
// une option de nettoyage des colonnes en fin de traitement est aussi possible (par défaut)
//----------------------------------------------------------------------------------------------

let fnSplitDynamicColumns =(
            pTable                          as any,
            pFieldSplit                     as text,
            optional ppDelim                as text,
            optional ppPrefixIndex          as text,
            optional pCleanUp               as logical

        ) =>     
        let

            Source = if pTable is table then
                        pTable
                        else  Excel.CurrentWorkbook(){[Name=pTable]}[Content],
          
            pDelim= if ppDelim is null then
                       ","
                       else ppDelim,

            pPrefixIndex=if ppPrefixIndex is null then
                            "_"
                            else ppPrefixIndex,

            StrEval="each List.Count(Text.PositionOfAny([" & pFieldSplit  & "],{pDelim},Occurrence.All))",
            EvalListCount=Expression.Evaluate(StrEval,[List.Count=List.Count, Text.PositionOfAny=Text.PositionOfAny, pDelim=pDelim, Occurrence.All=Occurrence.All]),
          
            TableDynamicColumnList =
                List.Transform(
                    {1 ..
                    List.Max(Table.AddColumn(
                        Source,
                        "CustomedField",
                        EvalListCount
                        )[CustomedField]
                    ) + 1
                    },
                    each pFieldSplit & pPrefixIndex & Text.From(_)
                ),
          
            TableSplitColumnDelimiter =
                Table.SplitColumn(
                    Source, pFieldSplit,
                    Splitter.SplitTextByDelimiter(pDelim, QuoteStyle.Csv),
                    TableDynamicColumnList
                ),

            ListColumnNames=Table.ColumnNames(TableSplitColumnDelimiter),

            isTbCleanUp = if pCleanUp is null or pCleanUp = true then
                                let
                                    CleanColumnsTable = Table.TransformColumns(TableSplitColumnDelimiter, List.Transform(ListColumnNames, each {_, Text.Clean, type text} ) ),
                                    TrimColumnsTable = Table.TransformColumns(CleanColumnsTable, List.Transform(ListColumnNames, each {_, Text.Trim, type text} ) )
                                in
                                    TrimColumnsTable
                            else TableSplitColumnDelimiter
          
        in
            isTbCleanUp

in
    fnSplitDynamicColumns

Utilisation
PowerQuery:
let
    t= fnSplitDynamicColumns (
            "TB_DATA",
            "COMPETENCES",
            ",",
            ".",
            null)
in
    t

PowerQuery:
let
    Source = fnSplitDynamicColumns("TB_DATA", "COMPETENCES", null, "#", false)
in
    Source
Avec une variante... je vous laisse découvrir dans le fichier joint

1708807661485.png


1708807678177.png
 

Pièces jointes

  • SplitColumns_V0.008.xlsx
    35.9 KB · Affichages: 5

Discussions similaires

Statistiques des forums

Discussions
314 422
Messages
2 109 449
Membres
110 483
dernier inscrit
Laanvy