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 colAcumulado
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:
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 Fin
A 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.