martes, 14 de septiembre de 2021

Power Query: Expandir columnas con condición

Continuando con las posibilidades que ofrece Power Query en cuanto a formas de combinar-unir distintas tablas o consultas (revisa las entradas previas respecto a Table.Join, Table.SelectRows o Table.AddJoinColumn).
En la mayoría de los casos, una vez realizadas las uniones o 'joins' nos encontramos con una nueva columna que debemos expandir... y sin las relaciones son muchas, se hace un poco tedioso :-(

Por este motivo hoy veremos un poco de código M que nos permitirá expandir las columnas cuando se cumplan ciertos criterios (obviamente las que puedan ser expandidas jeje).

Se trata por tanto de expandir las Tablas contenidas en las columnas procedentes de una join cuando cumplan ciertos patrones...

Veamos un ejemplo sencillo...
Empezaremos cargando solo como conexión dos tablas de nuestra hoja de cálculo: 'TblALT_ED' y 'TblCOMISION
Power Query: Expandir automáticamente todas las columnas

En este ejercicio me interesa que notes que la TblCOMISION tiene además de filas vacías, elementos duplicados!!.
Sabemos que esto es un problema, ya que en combinaciones 'normales' (con Table.NestedJoin) obtendremos duplicidades en aquellos registros 'duplicados'!!
Lo interesante es que el código que escribiremos a continuación permite controlar esta situación y tomar una decisión al respecto...

Así pues, tras la carga de ambas tablas en el editor de consultas de Power Query abriremos una Consulta en blanco e introduciremos el siguiente código M:
let
    //Añadimos una nueva columna vinculada a la TblCOMISION
    Origen = Table.AddJoinColumn(TblALT_ED,{"Producto","Comercial"},
                                TblCOMISION,{"Cod","Vendedor"},
                                "DATA_COMISION"),
    //generamos una lista con los nombres de las columnas de TblCOMISION
    //lo cargamos en el Buffer para facilitar posteriores usos de la lista
    CamposTblCOMISION=List.Buffer(Table.ColumnNames(TblCOMISION)),

    //Incorporamos, por facilidad, una columna tipo Índice
    AñadeId=Table.AddIndexColumn(Origen,"Id",0,1),

    //Creamos una nueva columna, a partir de la generada con Table.AddJoinColumn
    //donde segmentamos aquellas Tablas con varias filas,
    // de los que solo contienen una fila de información (los que nos interesan...)
    //además, en los casos afirmativos (i.e., con datos), convertimos la tabla en Record
    AddColumnaExpandida = Table.AddColumn(AñadeId, 
        "AddCol_Expande", 
        each 
            if Table.RowCount([DATA_COMISION])>1 then 
                null 
            else
                Origen[DATA_COMISION]{[Id]}{0}),

    //Y preparamos un proceso para recorrer todas las columnas de nuestra tabla
    IncorporoColumnas=
        let
        origen = AddColumnaExpandida,

        //contamos el número de elementos/columnas de la lista
        NumCols = List.Count( CamposTblCOMISION ),

        //creamos una función recursiva
        AddColumns = ( tabla as table, contador as number ) as table =>
            let
                //agregamos a una tabla con datos vacíos en este caso (each null)
                //con el nombre tomado de nuestra lista
                AgregoCol = Table.AddColumn( tabla, 
                                    CamposTblCOMISION{contador}, 
                                    each if [AddCol_Expande]=null then 
                                        null 
                                    else 
                                        Record.Field(Origen[DATA_COMISION]{[Id]}{0}, CamposTblCOMISION{contador}) ),
                //montamos el bucle y salida de este
                //mientras que el contador no supere el número de columnas a incorporar
                //OJO!!, listas en base 0
                ColAgregada = if ( contador < NumCols ) then @AddColumns( AgregoCol, contador + 1 ) else tabla
            in
                ColAgregada,

        //para finalmente aplicar nuestra función recursiva sobre la tabla original
        TablaFinal = AddColumns( origen, 0 )
    in
        TablaFinal,
    
    //quitamos las columnas que no necesitamos...
    ColumnasQuitadas = Table.RemoveColumns(IncorporoColumnas,{"Id", "AddCol_Expande", "DATA_COMISION"})
in 
    ColumnasQuitadas

Power Query: Expandir automáticamente todas las columnas

Observamos como el número de filas coincide con las iniciales de la 'TblALT_ED', es decir, no existen duplicidades...
Además, en aquellos casos en los que se hubiera producido la duplicidad, con nuestro código, hemos logrado resaltarlos dejándolos vacíos...

Otro aspecto importante ha sido el uso de una función recursiva (lee algo más sobre esto), que nos ha permitido recorrer cada columna de nuestra tabla en busca de las que se debían expandir...

Y por finalizar la entrada de hoy, os dejo una alternativa al código anterior, donde en lugar de dejar vacío el registro (para aquellos casos con duplicidades en los items), retornamos la media aritmética del dato:
let
    Origen = Table.AddJoinColumn(TblALT_ED,{"Producto","Comercial"},
                                TblCOMISION,{"Cod","Vendedor"},
                                "DATA_COMISION"),

    CamposTblCOMISION=List.Buffer(Table.ColumnNames(TblCOMISION)),

    AñadeId=Table.AddIndexColumn(Origen,"Id",0,1),

    //Aquí generamos la nueva columna donde, a partir de la creada con AddJoinColumn
    //añadimos la tabla resultante de la join
    //o la tabla agrupada con un cálculo de Media
    AddColumnaExpandida = Table.AddColumn(AñadeId, 
        "AddCol_Expande", 
        each 
            if Table.RowCount([DATA_COMISION])>1 then 
                Table.Group(Origen[DATA_COMISION]{[Id]},
                        {"Cod","Vendedor"}, 
                        {{"Comisión", each List.Average([Comisión]), type nullable number}}){0} 
            else
                Origen[DATA_COMISION]{[Id]}{0}),


    IncorporoColumnas=
        let
        origen2 = AddColumnaExpandida,

        NumCols = List.Count( CamposTblCOMISION ),

        AddColumns = ( tabla as table, contador as number ) as table =>
            let
                AgregoCol = Table.AddColumn( tabla, 
                                    CamposTblCOMISION{contador}, 
                                    each 
                                        Record.Field(tabla[AddCol_Expande]{[Id]}, CamposTblCOMISION{contador}) ),

                ColAgregada = if ( contador < NumCols ) then @AddColumns( AgregoCol, contador + 1 ) else tabla
            in
                ColAgregada,

        TablaFinal = AddColumns( origen2, 0 )
    in
        TablaFinal,


    ColumnasQuitadas = Table.RemoveColumns(IncorporoColumnas,{"Id", "AddCol_Expande", "DATA_COMISION"})
in 
    ColumnasQuitadas

Power Query: Expandir automáticamente todas las columnas

Compara ambas consultas resultantes para aquellas filas con el problema de duplicidades...
Muy interesante para dar una respuesta al problema de tablas con repetidos.

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.