My notesPractical Power BI tips
CALCULATE replaces the filter on that column: day 1 of the DAX filter series

You set a year slicer to 2024 on the dashboard, and the card showing Sales 2025 keeps displaying 2025. No bug, no stale cache, no broken relationship. This is day 1 of the DAX filter series: we look at what CALCULATE actually does to your filter context, and why that behavior explains so many “unexpected” outcomes.
The only DAX function that puts filtering inside the measure
Most measures simply receive whatever is in the filter context: the slicer the user set, the page filter, the visual filter. They look around and calculate based on what is currently active. CALCULATE works differently.
CALCULATE([Sales], 'Date'[Year] = 2025) literally says: evaluate [Sales], but use 2025 as the filter on Date[Year]. That instruction lives inside the measure, not in the report. That is the core of what CALCULATE does: it is the only DAX function that lets you pass a modified filter context to the expression you are evaluating, instead of relying on what the visual or the slicer provides.
Sales 2025 = CALCULATE([Sales], 'Date'[Year] = 2025) looks harmless when you put it on a card without other filters. You get exactly the 2025 total. The assumption you easily take away is that CALCULATE added a filter to what was already there. That assumption holds for exactly one screenshot.
Where the slicer loses
Same card, but now on a report page with a year slicer. The user sets the slicer to 2024. At that point two filters arrive at the card for Date[Year]: the slicer sets Year = 2024, and the measure already has Year = 2025 in place. One column, two claims. DAX resolves that with a clear rule: the CALCULATE filter wins. The card keeps showing 2025.
This is not a model error, a missing relationship, or a wrong setting. The measure works exactly as written. The confusion comes from the slicer feeling like it should do something, while it has already been overwritten on that specific column.
The rule: per column, not the whole report
The override is per column. Only the column you name in CALCULATE loses its external filter. All other filters in the report context stay active.
A country slicer on Customer[Country] still works on the same card, even when the year slicer on the dashboard has no effect. A segment filter, a product filter, a page filter: none of those are touched. Only Date[Year] is overwritten, because that is the column you named in the measure.
That column-by-column thinking is the key. Almost every time a measure does something “unexpected” in a dashboard, there is a CALCULATE filter on the same column as an active slicer. The rule is consistent, the outcome is predictable, once you know how to look.
What to check in your own model
Open a measure that carries a hard-coded filter: something like a time intelligence measure (Sales Last Year) or a segment-specific measure (Sales Retail). Look at which column it explicitly filters. Then check whether a slicer on that same column in the report still affects the visual.
If the slicer has no effect, that is the override rule at work, and the measure has already claimed that column. That is exactly the intended behavior when you build a time-filtered measure. It becomes a surprise when you did not know it, and doubly confusing when you try to explain your report to a colleague who expects the slicer to control everything.
Every measure that carries a hard-coded filter makes that one column immune to slicers filtering the same field. Knowing which columns those are in your model is the beginning of DAX fluency: instead of looking at an “unexpected” number, you look at which filters are currently active and which ones the measure has already overwritten.
Tomorrow: FILTER
This is day 1 of a five-part series on DAX filter logic. Today covered the base rule of CALCULATE: on the column you name, your own filter replaces the external one. Tomorrow we continue with FILTER, the first function you put inside CALCULATE to extend your filter logic, and the start of the patterns that let a slicer participate again rather than being overwritten. More to come.
The whole series is summarized in the DAX filter cheat sheet.
More at trainerbjorn.nl.