martes, 17 de enero de 2023

Power Query: Un Record de 'pasos'

Trabajar con Records en Power Query siempre es interesante y práctico... Te recomiendo leas este artículo de hace un par de años, plenamente vigente: Trabajar con Records.

En ese artículo se describen algunos detalles de los 'Records' (desde los más simples a algunos avanzados), de entre los cuales para el artículo de hoy, me interesa detenerme en qué tipo de datos podemos añadir a un Record:
- valores de texto, fecha, numéricos...
- Listas de todo tipo
- otros Records
- y en especial, también admite Tablas!!

Este es un punto interesante, ya que nos abre un abanico de posibilidades... La idea es trabajar con Tablas como parte de un Record.

Seguramente no te hayas percatado de una opción por defecto cuando cargamos datos de un rango o tabla, donde se gestionan automáticamente esos datos a través de un Record.
Veámoslo con un ejemplo. Partiremos de dos tablas en nuestra hoja de cálculo: TblVENTAS y TblPRECIOS
Power Query: Un Record de 'pasos'

Cuando realizamos el proceso de carga de datos con cualquiera de las opciones conocidas y entramos en el código generado de la consulta vemos:
let
    Origen = Excel.CurrentWorkbook(){[Name="TblVENTAS"]}[Content]
in
    Origen

Si desglosamos las partes de esa línea tenemos:
1- Excel.CurrentWorkbook(): con el que obtenemos una Tabla con todos los rangos (dinámicos o con nombres definidos) y tablas empleadas.
2- al añadirle la extensión, OJO ahora!!: {[Name="TblVENTAS"]} obtenemos un Record que contiene en uno de sus campos/fields una Tabla con el contenido de ésta!!!.
En este punto indicamos que nos retorne el registro de la tabla anterior que coincida, en la columna 'Name' con el texto 'TblVENTAS' (una 'especie' de filtro...)
3- información que recuperamos fácilmente reclamando o llamando a ese campo:[Content]
Esta llamada muestra el contenido de esa Tabla que existía dentro del campo de nuestro registro...
¡¡Increible lo que ocurre en una sola línea de código!!.

Pero esto no es lo más interesante de los Records...
Imagina que has realizado una transformación de n pasos en tu consulta.. por ejemplo:
let
      Origen = Excel.CurrentWorkbook(){[Name="TblVENTAS"]}[Content],
    TipoCambiado = Table.TransformColumnTypes(Origen,{{"Fechas", type date}, {"Artículo", type text}, {"Unidades", Int64.Type}}),
    NombreMes = Table.TransformColumns(TipoCambiado, {{"Fechas", each Date.MonthName(_), type text}}),
    Agrupacion = Table.Group(NombreMes, {"Fechas", "Artículo"}, {{"Acum_Uds", each List.Sum([Unidades]), type nullable number}})
    in
    Agrupacion

un ejemplo sencillo de query donde obtenemos los datos de una Tabla de la hoja de cálculo, para luego cambiar los tipos de datos de las diferentes columnas, transformar el campo Fecha para visualizar el nombre del mes, y acabar realizando una doble agrupación por nombre del mes y artículo...
Nada especial... pero fíjate ahora en el cambio que vamos a realizar en el código:
[
      Origen = Excel.CurrentWorkbook(){[Name="TblVENTAS"]}[Content],
    TipoCambiado = Table.TransformColumnTypes(Origen,{{"Fechas", type date}, {"Artículo", type text}, {"Unidades", Int64.Type}}),
    NombreMes = Table.TransformColumns(TipoCambiado, {{"Fechas", each Date.MonthName(_), type text}}),
    Agrupacion = Table.Group(NombreMes, {"Fechas", "Artículo"}, {{"Acum_Uds", each List.Sum([Unidades]), type nullable number}})
    ]

Eliminamos la expresión let ... in ..., sustituyéndola por los corchetes [...].
Esto convertira nuestro proceso en un registro, donde el contenido de cada paso (sea Lista, Tabla, Registro o Valor), se carga en un campo del recién Record creado:
Power Query: Un Record de 'pasos'


Tenemos un Record compuesto por distintos campos, uno por cada paso!!. Alucinante!
A partir de aquí podemos trabajar sobre ese Record como con cualquiera creado de la forma tradicional...
Por ejemplo, recuperamos la Tabla del campo 'Agrupacion' (era el último paso de nuestra consulta), para combinarlo con otra Tabla y finalizar expandiendo la info requerida:
let
    //obtenemos el campo 'Agrupacion' del Record 'VENTAS'
    Origen = VENTAS[Agrupacion],

    //para conbinar el contenido de ese campo (una tabla) con una segunda tabla (TblPRECIOS)
    CombinoPRECIOS = Table.NestedJoin(Origen, {"Artículo"}, PRECIOS, {"Pdto"}, "PRECIOS", JoinKind.LeftOuter),
    //y finalizar expandiendo un valor
    ExpandePRECIOS = Table.ExpandTableColumn(CombinoPRECIOS, "PRECIOS", {"Precio"}, {"Precio"})
in
    ExpandePRECIOS


O también podríamos incorporar un nuevo campo al Record generado, por ejemplo, la Tabla final generada en el ejemplo anterior:
let
    //obtenemos el campo 'Agrupacion' del Record 'VENTAS'
    Origen = VENTAS[Agrupacion],

    //para conbinar el contenido de ese campo (una tabla) con una segunda tabla (TblPRECIOS)
    CombinoPRECIOS = Table.NestedJoin(Origen, {"Artículo"}, PRECIOS, {"Pdto"}, "PRECIOS", JoinKind.LeftOuter),
    //y finalizar expandiendo un valor
    ExpandePRECIOS = Table.ExpandTableColumn(CombinoPRECIOS, "PRECIOS", {"Precio"}, {"Precio"}),

    //Incorporamos al REcord VENTAS un nuevo campo que contiene la Tabla previa
    NuevoRecord= VENTAS & [ExpandePRECIOS=ExpandePRECIOS]
in
    NuevoRecord


O un último ejemplo, recuperamos un campo de nuestro Record, para luego seleccionar alguna columna de la Tabla contenida en dicho campo:
let
    //obtenemos el campo 'Agrupacion' del Record 'VENTAS'
    Origen = VENTAS[Agrupacion],

    //para conbinar el contenido de ese campo (una tabla) con una segunda tabla (TblPRECIOS)
    CombinoPRECIOS = Table.NestedJoin(Origen, {"Artículo"}, PRECIOS, {"Pdto"}, "PRECIOS", JoinKind.LeftOuter),
    //y finalizar expandiendo un valor
    ExpandePRECIOS = Table.ExpandTableColumn(CombinoPRECIOS, "PRECIOS", {"Precio"}, {"Precio"}),

    //Incorporamos al REcord VENTAS un nuevo campo que contiene la Tabla previa
    NuevoRecord= VENTAS & [ExpandePRECIOS=ExpandePRECIOS],

    //Del nuevo registro creado, recuperamos uno de sus campos
    //recuerda que el contenido, en este caso, son Tablas
    //Y de esa tabla seleccionamos dos de sus columnas
    Seleccion = NuevoRecord[ExpandePRECIOS][[Artículo],[Precio]]
in
    Seleccion


Y mil posibilidades más...

En definitiva, realizar esta conversión de Query a Record facilita el traspaso de información entre nuestras 'consultas', y sobre todo agiliza el trabajo a la hora de procesar nuestros datos.

No hay comentarios:

Publicar un comentario

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