Cálculo recursivo / iterativo en Power Query

Un usuario Pregunto ✅

Lluvioso1982

Hola todos,

Necesito tu ayuda para resolver un problema.

Estoy tratando de calcular un nuevo valor de una fila usando el valor anterior de la fila.

Mis intentos de usar Dax terminaron en dependencias circulares.

Mi esperanza es que lo que quiero hacer sea posible en Power Query usando M.

Construí la siguiente consulta / tabla:

Rainy1982_0-1606660926324.png

BOZ1 son algunos datos históricos, esta columna no cambiará con la actualización y no se agregarán nuevos valores.

Para calcular el Nuevo valor desde el 24/11/20 en adelante necesito tomar el 144 como punto de partida y restar el valor en VOZ: 144 – 0,46 = 143,54. Este será mi valor para el 24/11/20.

El valor para 25/11/20 es 143,54-0 = 143,54 y así sucesivamente.

No estoy seguro de como proceder.

Con la ayuda de Google, descubrí dos posibles soluciones:

1. Escribe un bucle como una función personalizada e invocalo para agregar una nueva columna.

o

2. Utilice esta solución: https://stackoverflow.com/questions/57460424/iterative-calculation-in-power-query

Ambas soluciones están muy por encima de mis habilidades actuales.

Espero que alguien pueda ayudarme, ya que este problema realmente me mantiene despierto por la noche.

Atentamente

Lluvia

ImkeF

Hola @ Rainy1982,

pegue el siguiente código en el editor avanzado y siga los pasos:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjLRMzTUMzIwMlDSUTKzNAaSQGSgZ2JmCARKsTpAJcYoSoyApKGJCUhhbCwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Datum = _t, Index = _t, BOZ1 = _t, #"VOZ Sys1" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Datum", type date}, {"BOZ1", Int64.Type}, {"VOZ Sys1", type number}, {"Index", Int64.Type}}),
    BufferedStart = Table.Buffer( Table.Sort(#"Changed Type",{{"Index", Order.Ascending}}) ),
    Initial = BufferedStart{0},
    ListGenerate = List.Generate( ()=>
    [Result = Initial[BOZ1], Counter = 0],
    each [Counter] < Table.RowCount(BufferedStart),
    each [
        Result = [Result] - BufferedStart[VOZ Sys1]{Counter},
        Counter = [Counter] + 1
    ],
    each [Result]
),
    Custom1 = Table.FromColumns(Table.ToColumns(BufferedStart) & {ListGenerate} , Table.ColumnNames(BufferedStart) & {"Result"})
in
    Custom1

Para adaptarlo a su solución, debe reemplazar el código en el primer paso (Fuente) por una referencia a nuestra tabla.

Jimmy801

Hola @ Rainy1982

puede aplicar un Table.Distinct en su columna de índice y luego agregar esta fórmula a una columna personalizada

try RemovedDuplicates{[Index= [Index]-1]}[BOZ1] - [VOZ Sys1] otherwise null

Aquí el ejemplo completo

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjLRMzTUMzIwMlDSUTKzNAaSQGSgY2JmCARKsTpAJcYoSoyApKGJCUhhbCwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Datum = _t, Index = _t, BOZ1 = _t, #"VOZ Sys1" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Datum", type date}, {"BOZ1", Int64.Type}, {"VOZ Sys1", type number}, {"Index", Int64.Type}}, "de-DE"),
    RemovedDuplicates = Table.Buffer(Table.Distinct(#"Changed Type", {"Index"})),
    #"Added Custom" = Table.AddColumn(RemovedDuplicates, "Result", each  try RemovedDuplicates{[Index= [Index]-1]}[BOZ1] - [VOZ Sys1] otherwise null )
in
    #"Added Custom"

El rendimiento de esto también debería ser muy bueno

Copie y pegue este código en el editor avanzado en una nueva consulta en blanco para ver cómo funciona la solución.

Si esta publicación ayuda o resuelve su problema, márquelo como solución (para ayudar a otros usuarios a encontrar contenido útil y reconocer el trabajo de los usuarios que lo ayudaron)
Los kudoes también son agradables

Divertirse

Palanqueta

ImkeF

Hola @ Rainy1982,

pegue el siguiente código en el editor avanzado y siga los pasos:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjLRMzTUMzIwMlDSUTKzNAaSQGSgZ2JmCARKsTpAJcYoSoyApKGJCUhhbCwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Datum = _t, Index = _t, BOZ1 = _t, #"VOZ Sys1" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Datum", type date}, {"BOZ1", Int64.Type}, {"VOZ Sys1", type number}, {"Index", Int64.Type}}),
    BufferedStart = Table.Buffer( Table.Sort(#"Changed Type",{{"Index", Order.Ascending}}) ),
    Initial = BufferedStart{0},
    ListGenerate = List.Generate( ()=>
    [Result = Initial[BOZ1], Counter = 0],
    each [Counter] < Table.RowCount(BufferedStart),
    each [
        Result = [Result] - BufferedStart[VOZ Sys1]{Counter},
        Counter = [Counter] + 1
    ],
    each [Result]
),
    Custom1 = Table.FromColumns(Table.ToColumns(BufferedStart) & {ListGenerate} , Table.ColumnNames(BufferedStart) & {"Result"})
in
    Custom1

Para adaptarlo a su solución, debe reemplazar el código en el primer paso (Fuente) por una referencia a nuestra tabla.

Lluvioso1982

En respuesta a ImkeF

Hola Imke,

muchas gracias, tu solución funcionó a las mil maravillas!

Todavía tengo que entender la solución en su conjunto, pero ser capaz de implementarla es un buen punto de partida.

Atentamente

Vanessa

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *