Forum Discussion

ldoriejhl's avatar
ldoriejhl
Frequent Visitor
2 years ago
Solved

Iterating over rows in table and portioning totals by group

Hi, Hopefully someone can help me with a particular task; I need to iterate over a table sequentially and recalculate a column (labelled "Received") based on both the value in the "Due" column and...
  • Chewdata's avatar
    2 years ago

    Hey,

    I've used a function to solve this. 
    The function creates to total received and running total for due.
    It then wil create a new column for receiverd.
    Based on a index it wil then check if de record is the last record of the particular plan. if so it wil calculate the remainder.


    Please try this code:

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WCshJzDPUDaksSDVU0lEyNDCAkwZKsTrI8kZAMSOwjAVOeWOoDHZZE7gsyAaYvBGa7UZopqPLY5M1gstaQIyAyxuj6TZBMx1dHpesKT5JhFZdoLrYWAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Plans = _t, Due = _t, Received = _t, #"Difference (wanted)" = _t]),
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Plans", type text}, {"Due", Int64.Type}, {"Received", Int64.Type}, {"Difference (wanted)", Int64.Type}}),
        #"Grouped Rows" = Table.Group(#"Changed Type", {"Plans"}, {{"Table", each _, type table [Plans=nullable text, Due=nullable number, Received=nullable number, #"Difference (wanted)"=nullable number]}}),
        
        // function
        fnRunningtotal = (vTable as table) =>
        let
            add_index = Table.AddIndexColumn(vTable, "Index", 1, 1, Int64.Type),
            add_DueTotal = Table.AddColumn(add_index, "DueTotal", each List.Sum(List.Range(add_index[Due], 0, [Index]))),
            add_ReceivedTotal = Table.AddColumn(add_DueTotal, "ReceivedTotal", each List.Sum(add_DueTotal[Received])),
            add_Received = Table.AddColumn(add_ReceivedTotal, "ReceivedNew", each if [Index] = List.Max(add_ReceivedTotal[Index]) then  [Due] + ([ReceivedTotal] - [DueTotal]) else if [ReceivedTotal] >= [DueTotal] then [Due] else [DueTotal] - [ReceivedTotal], Int64.Type),
            add_Difference = Table.AddColumn(add_Received, "Difference", each if [Index] = List.Max(add_Received[Index]) then [DueTotal] - [ReceivedTotal] else 0, Int64.Type) 
        in
            add_Difference,
    
        inv_fnRunningtotal = Table.TransformColumns(#"Grouped Rows", {"Table", fnRunningtotal}),
        #"Expanded Table" = Table.ExpandTableColumn(inv_fnRunningtotal, "Table", {"Plans", "Due", "ReceivedNew", "Difference"}, {"Plans.1", "Due", "Received", "Difference"})
    
    in
        #"Expanded Table"