Forum Discussion
Calculate Running Total Using Measures
Hi Lyssillic
agree with v-easonf-msft : the logic is understandable, but unfortunately my DAX skills are not good enough to come up with a solution here. Problem is that you need "real" recurion to set back to 0 with regards to the previous value. Problem with the current formula is that the negative running total caused by the 14 "under" will have to be compensated by the following overs before getting positive again.
With regards on how to convert your existing measure to a calculated column - it would be this:
RunningTotal =
var filterDate = LASTDATE(Sheet1[Date])
var output = CALCULATE(
SUMX(Sheet1, IF (
[Under] > 0,
[Over] - [Under],
[Over]
)),
ALL(Sheet1),
Sheet1[Date] <= filterDate
)
RETURN IF (
output > 0,
output,
0
)
But it will just return the same value than your current measure in the column.
In Power Query one would use List.Generate or List.Accumulate, but if you run them without a Table.Buffer (as this wouldn't work in Direct Query mode) the result will be very slow for larger datasets.
Posting the PQ sample here in case it helps some DAX genius to pick up the logic:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlDSUTKBYgNDXSAyMjC0VIrVgUgZggmwpBGKpKEhSAyIjUG0MaqcCVQOjE0wDIXbZ4pVygIkZYZVytAIJGeOkIsFAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Under = _t, Over = _t, #"Running Over Total - Under" = _t, Date = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Under", Int64.Type}, {"Over", Int64.Type}, {"Running Over Total - Under", Int64.Type}, {"Date", type date}}),
BufferedTable = Table.Buffer(#"Changed Type"),
RunningTotal = List.Skip(List.Generate( () =>
[RowResult = 0, CumulativeResult = 0, Counter = 0],
each [Counter] <= Table.RowCount(BufferedTable),
each [
CurrentRow = BufferedTable{[Counter]},
RowResult = if CurrentRow[Under] > 0
then CurrentRow[Over] - CurrentRow[Under]
else CurrentRow[Over],
CumulativeResult = List.Max( { [CumulativeResult] + RowResult, 0 } ),
Counter = [Counter] + 1
],
each [CumulativeResult]
)),
Result = Table.FromColumns( Table.ToColumns( BufferedTable ) & { RunningTotal }, Table.ColumnNames(BufferedTable) & {"RunningTotal"} )
in
Result
Actually, even without the buffer the complicated List.Generate-logic wouldn't work in Direct Query unfortunately.