Hoy veremos diferentes alternativas con Power Query para recuperar los últimos valores registrados, de acuerdo a distintas condiciones.
A partir de nuestra tabla de datos, deseamos recuperar aquellos registros únicos que respondan a un criterio múltiple (País y Producto), pero que hayan sido los últimos en registrarse según un campo de orden, fecha, etc...
En concreto veremos tres técnicas que, con algunas diferencias, dan respuesta a nuestro problema.
En la imagen anterior, he señalado en color rojo los registros esperados, que responden a los últimos registros ocurridos para esa dupla: país+producto.
Cargamos la tabla al editor de Power Query.
Y duplicamos en dos ocasiones la consulta creada (hasta tener tres 'queries' iguales.
Las renombraremos como:
-TblORDEN_Opcion1
-TblORDEN_Opcion2
-TblORDEN_Opcion3
En la primera de ellas 'TblORDEN_Opcion1' usaremos la técnica de Quitar duplicados.
Para esto deberemos ordenar adecuadamente nuestros registros...
Por ejemplo ordenando por el campos: 'Orden' (en Descendente!!!, para que los más recientes queden en la parte superior)
Luego Quitaríamos duplicados (en el Editor de Power Query - botón derecho y Quitar duplicados sobre los campos: País & Producto)
La secuencia grabada sería:
En ambos casos el resultado es el correcto:
Fundamental en este caso el empleo de Table.Buffer.
En una entrada posterior explicaremos el por qué.
Otra posible solución la damos en la Opción 2.
Donde los pasos dados serían:
1- Agrupar por 'País' y 'Producto'
2- Modificar algo el código obtenido en Table.Group para conseguir ver el valor máximo del campo Orden
3- Acabar filtrando según las coincidencias obtenidas.
El código completo:
el resultado es el mismo... solo que este método requiere de más tiempo en su ejecución. Especialmente notable con bases de datos grandes...
La opción 3 es una variante de la anterior, pero con un poco de lenguaje M avanzado.
Vemos el código picado:
Tres técnicas interesantes a aplicar según el caso y el volumen de registros...
A partir de nuestra tabla de datos, deseamos recuperar aquellos registros únicos que respondan a un criterio múltiple (País y Producto), pero que hayan sido los últimos en registrarse según un campo de orden, fecha, etc...
En concreto veremos tres técnicas que, con algunas diferencias, dan respuesta a nuestro problema.
En la imagen anterior, he señalado en color rojo los registros esperados, que responden a los últimos registros ocurridos para esa dupla: país+producto.
Cargamos la tabla al editor de Power Query.
Y duplicamos en dos ocasiones la consulta creada (hasta tener tres 'queries' iguales.
Las renombraremos como:
-TblORDEN_Opcion1
-TblORDEN_Opcion2
-TblORDEN_Opcion3
En la primera de ellas 'TblORDEN_Opcion1' usaremos la técnica de Quitar duplicados.
Para esto deberemos ordenar adecuadamente nuestros registros...
Por ejemplo ordenando por el campos: 'Orden' (en Descendente!!!, para que los más recientes queden en la parte superior)
Luego Quitaríamos duplicados (en el Editor de Power Query - botón derecho y Quitar duplicados sobre los campos: País & Producto)
La secuencia grabada sería:
let
Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content],
Tipo_Cambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}),
Filas_Ordenadas = Table.Buffer(Table.Sort(Tipo_Cambiado,{{"Orden", Order.Descending}})),
Duplicados_Quitados = Table.Distinct(Filas_Ordenadas, {"País", "Producto"}),
Filas_Ordenadas1 = Table.Sort(Duplicados_Quitados,{{"País", Order.Ascending}, {"Producto", Order.Ascending}})
in
Filas_Ordenadas1
O algo más breve:let
Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content],
Tipo_Cambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}),
Filas_Ordenadas = Table.Buffer(Table.Sort(Tipo_Cambiado,{{"País", Order.Ascending}, {"Producto", Order.Ascending}})),
Duplicados_Quitados = Table.Distinct(Filas_Ordenadas, {"País", "Producto"})
in
Duplicados_QuitadosEn ambos casos el resultado es el correcto:
Fundamental en este caso el empleo de Table.Buffer.
En una entrada posterior explicaremos el por qué.
Otra posible solución la damos en la Opción 2.
Donde los pasos dados serían:
1- Agrupar por 'País' y 'Producto'
2- Modificar algo el código obtenido en Table.Group para conseguir ver el valor máximo del campo Orden
3- Acabar filtrando según las coincidencias obtenidas.
El código completo:
let
Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content],
TipoCambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}),
//agrupamos por País y Producto
//Y definimos que el cálculo a ver sea el dato mayor del campo Orden (List.Max([Orden])
FilasAgrupadas = Table.Group(TipoCambiado, {"País", "Producto"}, {{"Último", each List.Max([Orden]), type number}, {"ListPrecios", each _, type table [Orden=nullable number, País=nullable text, Producto=nullable text, Precio=nullable number]}}, GroupKind.Local),
//expandimos la agrupación, y recuperamos de nuevo los campos Orden y Precio
SeExpandió_ListPrecios = Table.ExpandTableColumn(FilasAgrupadas, "ListPrecios", {"Orden","Precio"}, {"Orden","Precio"}),
//para finalmente, en el conjunto de todas las combinaciones posibles,
//quedarnos con aquellos registros donde coincidan Orden y Ultimo
Filas_Filtradas = Table.SelectRows(SeExpandió_ListPrecios, each ([Orden] = [Último])),
//reordenamos las columnas
Columnas_Reordenadas = Table.ReorderColumns(Filas_Filtradas,{"Orden", "País", "Producto", "Precio", "Último"})
in
Columnas_Reordenadas el resultado es el mismo... solo que este método requiere de más tiempo en su ejecución. Especialmente notable con bases de datos grandes...
La opción 3 es una variante de la anterior, pero con un poco de lenguaje M avanzado.
Vemos el código picado:
let
Origen = Excel.CurrentWorkbook(){[Name="TblORDEN"]}[Content],
TipoCambiado = Table.TransformColumnTypes(Origen,{{"Orden", Int64.Type}, {"País", type text}, {"Producto", type text}, {"Precio", type number}}),
//agrupamos por Pais y Producto
//sobre los campos resultantes de una tabla filtrada por los registros correspondientes al valor de orden más alto
//se consigue ordenando por Descendente el campo Orden, y asignandole un Indice 1, y negativos al posible resto de registros
// filtrando solo con aquellos cuyo Indice =1, esto es, el mayor valor
FilasAgrupadas = Table.Group(
TipoCambiado,
{"País", "Producto"},
{
{"Último", each Table.SelectRows(
[tbl=Table.AddIndexColumn( Table.Sort(_,{{"Orden", Order.Descending}}), "Index", 1, -2, Int64.Type)][tbl] ,
each ([Index] = 1))}
}
),
//expandimos la tabla resultante de un solo registro
Expande_ListPrecios = Table.ExpandTableColumn(FilasAgrupadas, "Último", {"Orden","Precio"}, {"Orden","Precio"}),
//y reordenamos las columnas
ColumnasReordenadas = Table.ReorderColumns(Expande_ListPrecios,{"Orden", "País", "Producto", "Precio"})
in
ColumnasReordenadasTres técnicas interesantes a aplicar según el caso y el volumen de registros...




No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.