A Power BI running total is usually wrong because the measure
accumulates over the wrong date column, clears the entire date
selection, or evaluates at a grain different from the visual. Start with
a marked date table, an active relationship, and an explicit boundary
for the accumulation.
A reliable base pattern is:
Sales Amount =
SUM ( Sales[SalesAmount] )
Running Sales =
VAR LastVisibleDate =
MAX ( 'Date'[Date] )
RETURN
CALCULATE (
[Sales Amount],
FILTER (
ALL ( 'Date'[Date] ),
'Date'[Date] <= LastVisibleDate
)
)
That pattern is not universally correct. The seven checks below tell
you what to change.
Check 1: Use a real date
table
Your Date table should contain:
- one row per date;
- a unique date key;
- no blank dates;
- no gaps for classic time intelligence;
- a range that covers the fact data; and
- an active one-to-many relationship to the fact table.
Microsoft’s
date-table guidance explains the validation Power BI performs when a
table is marked as a date table, including unique, non-null, contiguous
values.
Use 'Date'[Date] on the visual axis. Do not use
Sales[OrderDate] while the measure removes filters from a
separate Date table. The axis and accumulation logic must operate on the
same calendar path.
If the calendar itself is suspect, work through the date-table
checklist first.
Check 2:
Capture the boundary before removing filters
This order matters:
Running Sales =
VAR LastVisibleDate =
MAX ( 'Date'[Date] )
RETURN
CALCULATE (
[Sales Amount],
FILTER (
ALL ( 'Date'[Date] ),
'Date'[Date] <= LastVisibleDate
)
)
LastVisibleDate is evaluated in the current visual cell
before CALCULATE changes the filter context.
If you calculate the maximum after clearing dates, the boundary can
become the last date in the entire model. Every row may then show the
final total.
Expose the boundary while debugging:
Running Total Boundary =
MAX ( 'Date'[Date] )
Add it to a table with the axis. It should advance one period at a
time.
Check 3:
Decide whether the running total should reset
A running total can mean:
- lifetime to date;
- year to date;
- within the currently selected period;
- within each customer, product, or project; or
- within a fiscal year.
For a calendar-year reset, use:
Sales YTD =
TOTALYTD (
[Sales Amount],
'Date'[Date]
)
For an explicit year boundary:
Running Sales by Year =
VAR LastVisibleDate = MAX ( 'Date'[Date] )
VAR VisibleYear = MAX ( 'Date'[Year] )
RETURN
CALCULATE (
[Sales Amount],
FILTER (
ALL ( 'Date' ),
'Date'[Year] = VisibleYear
&& 'Date'[Date] <= LastVisibleDate
)
)
Do not add a year reset simply because the chart “looks better.” The
reset must match the business definition.
Check 4:
Choose whether to respect the date slicer
This pattern can reach dates before the slicer’s start:
FILTER (
ALL ( 'Date'[Date] ),
'Date'[Date] <= LastVisibleDate
)
That may be correct for a lifetime balance. It may be wrong when the
desired total should begin at the first selected date.
To accumulate only over the selected set:
Running Sales in Selection =
VAR LastVisibleDate =
MAX ( 'Date'[Date] )
RETURN
CALCULATE (
[Sales Amount],
FILTER (
ALLSELECTED ( 'Date'[Date] ),
'Date'[Date] <= LastVisibleDate
)
)
ALLSELECTED keeps the outside selection while removing
the current row’s date. Test single-date, multi-date, and clear-slicer
states. For the broader distinction, see ALL vs ALLSELECTED vs
ALLEXCEPT.
Check 5: Match the visual
grain
A chart grouped by month does not necessarily have one date in
context. MAX ( 'Date'[Date] ) returns the last date of the
current month, which is usually the intended monthly boundary.
But a text month label such as Jan is not unique across
years. A visual grouped only by month name can combine January 2025 and
January 2026.
Use:
- a Year-Month key;
- a Year and Month hierarchy; or
- a sortable month-start date.
For example:
Month Start =
DATE ( YEAR ( 'Date'[Date] ), MONTH ( 'Date'[Date] ), 1 )
Make sure the axis uniquely identifies the period you intend to
accumulate.
Check 6: Verify the
active date relationship
Your running total may use 'Date'[Date] while the
business question expects Ship Date rather than Order Date.
If Order Date is active and Ship Date is inactive:
Shipped Sales =
CALCULATE (
[Sales Amount],
USERELATIONSHIP (
Sales[ShipDate],
'Date'[Date]
)
)
Then accumulate the measure:
Running Shipped Sales =
VAR LastVisibleDate = MAX ( 'Date'[Date] )
RETURN
CALCULATE (
[Shipped Sales],
FILTER (
ALLSELECTED ( 'Date'[Date] ),
'Date'[Date] <= LastVisibleDate
)
)
Activating the relationship inside the base measure keeps the
running-total wrapper reusable. See USERELATIONSHIP
for inactive date roles.
Check
7: Separate missing dates from missing transactions
A date table should provide every date even when no sales occurred.
That lets a chart show a continuous axis and carry the cumulative value
forward.
If the visual drops empty dates:
- use the Date-table field on the axis;
- enable Show items with no data where
appropriate; - confirm the Date table spans the period; and
- decide whether the display should show BLANK or the previous
balance.
Do not blindly replace every BLANK with zero. BLANK can mean the
requested date is outside the valid business range. The BLANK vs 0 guide helps define that
display rule.
Why the running
total repeats the final value
Common causes:
- the boundary is evaluated after date filters are removed;
- the visual axis comes from the fact table;
ALL ( 'Date' )clears Year while the formula never
reapplies it;- every axis label maps to the same maximum date; or
- the measure references a disconnected calendar.
Put these diagnostics in the same table:
First Visible Date = MIN ( 'Date'[Date] )
Last Visible Date = MAX ( 'Date'[Date] )
Visible Date Count = COUNTROWS ( VALUES ( 'Date'[Date] ) )
If the first and last date do not change by row, fix the visual/model
before the cumulative formula.
Why the
grand total looks different from the last row
The grand total evaluates the running-total measure in grand-total
filter context. It does not automatically copy the last visible row.
If the business rule says the total should display the value at the
last visible date, the base pattern often does that naturally. If it
does not, inspect what dates are visible at the total and whether
ALLSELECTED includes hidden periods.
The DAX grand-total guide
explains why totals recalculate rather than add displayed rows.
A running-total test grid
Verify:
- one day with transactions;
- one day without transactions;
- the first selected date;
- the last selected date;
- a year boundary;
- a product or customer slicer; and
- the grand total.
Write down whether the total should include dates before the
selection and whether it should reset. Those two decisions determine
most of the formula.
Frequently asked questions
Should a DAX
running total use ALL or ALLSELECTED?
Use ALL when the accumulation may reach outside the
visible date selection, such as a lifetime balance. Use
ALLSELECTED when it should begin with and remain inside the
selected dates.
Why does my
running total restart each month?
The filter-removal expression may clear only the day while retaining
the month, or the visual may use a disconnected Month field. Inspect the
columns still filtered inside the calculation.
Why is the running total
blank?
Check the date-table relationship, the fact-data range, and whether
the base measure returns BLANK at that date. Debug the base measure
before accumulating it.
Where can I test the measure?
Use the DAX
playground and expose the boundary date beside the cumulative
result. Compare ALL and ALLSELECTED under the
same slicer.