CALCULATE — главная функция DAX

Осваиваем CALCULATE — функцию, которая меняет контекст фильтра и открывает всю мощь DAX.

CALCULATE вычисляет выражение в изменённом контексте фильтра, заданном дополнительными условиями.

Почему CALCULATE — сердце DAX

Все агрегаты до сих пор считались «в том фильтре, что есть». Но аналитику постоянно нужно сравнивать: выручка этого региона против всех, продажи только премиум-товаров, доля в общем итоге. Для этого фильтр нужно изменить прямо в формуле — и единственная функция, которая это умеет, — CALCULATE. Понять её — значит понять DAX.

Синтаксис

CALCULATE( <выражение>, <фильтр1>, <фильтр2>, ... )

Первый аргумент — что считаем (обычно мера или агрегат). Дальше — условия, которые добавляются к текущему контексту фильтра (или заменяют его по столбцу). Примеры:

Выручка премиум = CALCULATE( [Выручка], Product[segment] = "Premium" )

Выручка всего = CALCULATE( [Выручка], ALL(Product) )

Доля сегмента = DIVIDE( [Выручка], CALCULATE([Выручка], ALL(Product)) )

Первая мера считает выручку, дополнительно отфильтровав товары премиум-сегмента. Вторая — снимает все фильтры с таблицы Product функцией ALL (получаем «итог по всем товарам» независимо от среза). Третья делит одно на другое и даёт долю сегмента в общем — классический приём «процент от итога».

Как CALCULATE меняет контекст

Было (контекст фильтра): регион = Юг
        │
        ▼  CALCULATE( [Выручка], Product[segment]="Premium" )
Стало: регион = Юг  И  segment = Premium
        │
        ▼  CALCULATE( [Выручка], ALL(Product) )
Стало: регион = Юг  (фильтр по Product СНЯТ функцией ALL)

Запомните два режима: обычный фильтр сужает контекст (добавляет условие), а функции семейства ALL / REMOVEFILTERS снимают фильтры с указанных таблиц или столбцов. Комбинируя их, вы получаете любые сравнения.

FILTER для сложных условий

Если условие сложнее простого равенства, внутрь CALCULATE кладут функцию FILTER, возвращающую таблицу нужных строк:

Крупные продажи = CALCULATE(
    [Выручка],
    FILTER( Sales, Sales[amount] > 10000 )
)
МодификаторЧто делает с фильтром
Стол[поле]=значдобавляет условие (сужает)
ALL(Таблица)снимает все фильтры с таблицы
REMOVEFILTERS()то же, более явно
FILTER(...)произвольное условие как таблица

Как работает под капотом

У CALCULATE есть скрытая суперспособность — context transition: она превращает текущий контекст строки в контекст фильтра. Поэтому когда меру (внутри которой неявно есть CALCULATE) вызывают в итераторе, она «знает» текущую строку как фильтр. Это объясняет, почему меры корректно работают в матрицах: каждая ячейка через переход контекста становится набором фильтров, и движок считает агрегат именно для неё.

Частые ошибки

  • Думать, что CALCULATE всегда заменяет фильтр. Простые условия добавляются к текущим; чтобы заменить — снимайте старые через ALL.
  • Считать «процент от итога» без ALL. Без снятия фильтра знаменатель равен числителю, и доля всегда 100%.
  • Грузить тяжёлый FILTER там, где хватит простого условия. Простое равенство быстрее, чем итерация по всей таблице.

Итог

  • CALCULATE считает выражение в изменённом контексте фильтра — это её единственное, но всемогущее назначение.
  • Простые условия сужают контекст; ALL/REMOVEFILTERS снимают фильтры (нужно для «процента от итога»).
  • Сложные условия задают через FILTER; под капотом CALCULATE делает переход контекста строки в фильтр.
Проверьте себя
1. Что делает функция CALCULATE?
AСортирует таблицу
BВычисляет выражение в изменённом контексте фильтра
CСоздаёт новую страницу отчёта
DМеняет тип столбца
2. Какая функция внутри CALCULATE нужна, чтобы посчитать «процент от общего итога»?
ASUM
BALL (снять фильтры для знаменателя)
CCOUNT
DMIN