Tiempo atrás escribí sobre cómo obtener un 'Running total' (acumulado creciente) sobre una tabla (ver aquí), donde empleamos una función M de Power Query: List.Sum.
Hoy nos adentraremos un poco más en este lenguaje y descubriremos algunas 'joyas' de esta programación:
List.Buffer(lista as list)
Carga la lista en la memoria. El resultado de esta llamada es una lista estable, lo que significa que tendrá un recuento determinado y un orden de los elementos.
List.Transform(lista as list, transformación as function)
Aplica la función/transformación en cada elemento de la lista y devuelve una nueva lista transformada.
List.Accumulate(lista as list, valor_incial as any, acumulador as function)
Acumula el resultado a partir de los valores de la lista dada; i.e., a partir del valor inicial, esta función aplica la función del acumulador y devuelve el resultado final acumulado.
En su momento empleamos la función List.Sum efectiva y válida cuando hay 'pocos' elementos sobre los que trabajar.. pero en ocasiones nuestras tablas contienen un número elevado de registros y List.Sum se hace 'pesado' y 'lento'.
Será en estos casos cuando podremos emplear las alternativas comentadas...
Partiremos de una tabla sencilla con cuatro campos: Fecha / Concepto / Debe / Haber
Trabajaremos de dos maneras.
Primero usando List.Transform y List.Buffer.
Cargaremos la Tabla al Editor de Power Query y en el editor avanzado añadiremos el siguiente código comentado:
Con lo que obtendremos es siguiente resultado esperado...
Segunda forma usando List.Accumulate.
Añadiremos una consulta en blanco y desde el editor avanzado añadiremos el siguiente código comentado:
A partir de lo que obtenemos...
Consiguiendo nuestra meta por dos nuevos caminos...
Hoy nos adentraremos un poco más en este lenguaje y descubriremos algunas 'joyas' de esta programación:
List.Buffer(lista as list)
Carga la lista en la memoria. El resultado de esta llamada es una lista estable, lo que significa que tendrá un recuento determinado y un orden de los elementos.
List.Transform(lista as list, transformación as function)
Aplica la función/transformación en cada elemento de la lista y devuelve una nueva lista transformada.
List.Accumulate(lista as list, valor_incial as any, acumulador as function)
Acumula el resultado a partir de los valores de la lista dada; i.e., a partir del valor inicial, esta función aplica la función del acumulador y devuelve el resultado final acumulado.
En su momento empleamos la función List.Sum efectiva y válida cuando hay 'pocos' elementos sobre los que trabajar.. pero en ocasiones nuestras tablas contienen un número elevado de registros y List.Sum se hace 'pesado' y 'lento'.
Será en estos casos cuando podremos emplear las alternativas comentadas...
Partiremos de una tabla sencilla con cuatro campos: Fecha / Concepto / Debe / Haber
Trabajaremos de dos maneras.
Primero usando List.Transform y List.Buffer.
Cargaremos la Tabla al Editor de Power Query y en el editor avanzado añadiremos el siguiente código comentado:
let
//carga los datos de la Tabla 'TblMov'
Origen = Excel.CurrentWorkbook(){[Name="TblMov"]}[Content],
//obtenemos el cálculo del saldo como diferencia de Debe-haber
colSaldo = Table.AddColumn(Origen, "Saldo", each (if [Debe] = "" then 0 else [Debe]) - (if [Haber] = "" then 0 else [Haber])),
//añadimos un columna de índice
colIndice = Table.AddIndexColumn(colSaldo,"TempIndex"),
//recuperamos(duplicamos el dato de la columna de Saldo
Input = colIndice[Saldo],
//generamos una lista nueva para cada registro de la tabla,
//calculada como la suma del saldo del registro más el dato del registro anterior del campo que estamos creando
//y la cargamos en memoria con List.Buffer
Output = List.Buffer(List.Transform({0..List.Count(Input)-1}, each Input{_} + (if _ = 0 then 0 else @Output{_-1}))),
//recuperamos de la memoria el dato acumulado
colAcumulado = Table.AddColumn(colIndice, "Acumulado", each Output{[TempIndex]})
in
colAcumuladoCon lo que obtendremos es siguiente resultado esperado...
Segunda forma usando List.Accumulate.
Añadiremos una consulta en blanco y desde el editor avanzado añadiremos el siguiente código comentado:
let
//cargamos la tabla desde la hoja de cálculo
Origen = Excel.CurrentWorkbook(){[Name="TblMov"]}[Content],
//calculamos el Saldo para cada registro como diferencia de Debe-Haber
colSaldo = Table.AddColumn(Origen, "Saldo", each (if [Debe] = "" then 0 else [Debe]) - (if [Haber] = "" then 0 else [Haber])),
//añadimos una columna de índice
colIndice = Table.AddIndexColumn(colSaldo,"TempIndex"),
//añadimos una columna personalizada con el cálculo Acumulado requerido
//List.Accumulate acumula el rango variable obtenido por List.Range
Fin = Table.AddColumn(colIndice, "Acum",
each List.Accumulate(
List.Range(colIndice[Saldo],0,[TempIndex]+1),
0,
(state, current) => state + current
))
in
FinA partir de lo que obtenemos...
Consiguiendo nuestra meta por dos nuevos caminos...







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