You can adjust your attempt like this:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
)
)
Note that you can include more filtering conditions in the FILTER
function by joining more conditions with &&
. You can add more filter conditions inside CALCULATE
as well. Here's an example:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
&& DataSource[Start Date] > DATE( 2018, 12, 31 )
),
DataSource[Phase] = "Scope"
)
The documentation for CALCULATE
and FILTER
might be useful for further clarification:
https://dax.guide/calculate/
https://learn.microsoft.com/en-us/dax/calculate-function-dax
https://dax.guide/filter/
https://learn.microsoft.com/en-us/dax/filter-function-dax
If you are trying to write this formula in a calculated column, it will not work as expected and you will need to use EARLIER
instead of MAX
:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= EARLIER( DataSource[End Date] )
)
)
The reason for this is that in a measure MAX
is calculated within its local filter context but in a calculated column the context is different and you use EARLIER
to refer to the earlier row context, that is, the End Date
in the current row of the larger table (rather than the smaller FILTER
table).
If you want something that works either as a measure or a calculated column, then @RADO's solution is pretty close and you can write this:
Cumulative Days Past Due =
VAR CurrDate =
CALCULATE( MAX( DataSource[Start Date] ) )
RETURN
CALCULATE(
SUM( DataSource[Days Past Due] ),
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= CurrDate
)
In this version, the MAX
works just as it did before in the first version above and it should also work in a calculated measure because wrapping the MAX
in a CALCULATE
performs a context transition that transforms the row context into a filter context corresponding to that single row.
You can drop the CALCULATE
wrapper for just a measure and drop both the CALCULATE
and MAX
functions for a simpler calculated column. In either of these cases, this variable version is likely the more performant one since the ALLEXCEPT
function is optimized to work efficiently within CALCULATE
rather than having to instantiate a new table when using FILTER
.
For further details on cumulative totals, I recommend DAX Patterns as a resource:
https://www.daxpatterns.com/cumulative-total/