Если запомнить из всего DAX одну функцию — это CALCULATE. Она делает то, чего не умеет ни одна другая: меняет контекст фильтра перед расчётом. Почти каждая нетривиальная мера — план-факт, доля, нарастающий итог, прошлый год — внутри опирается на CALCULATE.
Что она делает
Обычная мера считается в том контексте, что дал отчёт. CALCULATE позволяет этот контекст переписать:
CALCULATE ( выражение, фильтр1, фильтр2, ... )
Первый аргумент — что считать. Дальше — фильтры, которые применяются до расчёта.
Выручка по молочке =
CALCULATE ( [Выручка], Товары[Категория] = "Молочка" )
Эта мера всегда покажет выручку молочки — даже если в отчёте выбрана другая категория. CALCULATE переписал контекст: «считай выручку, но категорию зафиксируй на молочке».
Помните СУММЕСЛИ(Регион; "ЦФО"; Сумма) из Excel? CALCULATE([Выручка], Регионы[Регион]="ЦФО") — это он и есть, только мера переиспользуется и фильтр можно собрать любой сложности. CALCULATE — это «СУММЕСЛИ на стероидах».
Несколько фильтров = И
Фильтров можно передать сколько угодно — они складываются по «И»:
Выручка молочки в ЦФО =
CALCULATE (
[Выручка],
Товары[Категория] = "Молочка",
Регионы[Регион] = "ЦФО"
)
Молочка и ЦФО одновременно.
Зачем это на практике
CALCULATE — основа большинства управленческих мер. Пара примеров.
Доля категории в общем итоге — знаменатель считаем, сняв фильтр по категории:
Доля категории =
DIVIDE ( [Выручка], CALCULATE ( [Выручка], ALL ( Товары[Категория] ) ) )
Тут ALL убирает фильтр категории, и в знаменателе — выручка по всем категориям. Функции, которые так управляют фильтрами (ALL, FILTER, ALLSELECTED), — тема следующего урока; здесь важно увидеть, что они работают внутри CALCULATE.
Фиксированная база для сравнения — выручка за конкретный год, чтобы сравнить с ней:
Выручка 2026 =
CALCULATE ( [Выручка], Календарь[Год] = 2026 )
Переход контекста
Есть тонкость, которую достаточно знать на уровне идеи. Когда CALCULATE (или итератор с мерой внутри) стоит на строке таблицы, эта строка превращается в фильтр — «переход контекста». Именно поэтому [Выручка] внутри AVERAGEX из прошлого урока считалась по одному заказу. Глубоко копать не нужно: просто помните, что CALCULATE умеет превращать «текущую строку» в фильтр.
Соблазн написать IF ( SELECTEDVALUE(...) = "Молочка", [Выручка] ) вместо CALCULATE. Это не меняет контекст — это лишь прячет/показывает уже посчитанное число. Менять, что именно считается, умеет только CALCULATE.
Посчитайте выручку только по ЦФО: Выручка ЦФО = CALCULATE ( [Выручка], Регионы[Регион] = "ЦФО" ). Сколько выйдет и какова доля ЦФО в общей выручке?
Показать ответ
Выручка ЦФО = 2 523 688 ₽, доля ≈ 25,7 % (2 523 688 / 9 826 588). Если вышло 9 826 588 — фильтр не сработал: проверьте, что имя региона написано точно как в справочнике Регионы.
Что дальше
CALCULATE меняет контекст с помощью фильтров. Но фильтры бывают хитрее, чем «категория = молочка»: убрать все фильтры, оставить только пользовательский срез, наложить сложное условие. Этим занимается отдельная группа функций — фильтрующие. Следующий урок.