Если контекст фильтра — это набор правил, по которым DAX смотрит на данные, то CALCULATE() — это ваша суперспособность, которая позволяет переписывать эти правила.
Это самая мощная и, возможно, самая важная функция в DAX. Освоив CALCULATE, вы откроете для себя безграничные возможности аналитики.
Зачем нужна CALCULATE()?
CALCULATE позволяет вам:
● Удалять фильтры: Временно игнорировать существующие фильтры.
● Добавлять новые фильтры: Применять дополнительные фильтры, которые не были активны.
● Изменять существующие фильтры: Заменять активные фильтры на новые.
Это позволяет выполнять такие задачи, как:
● Расчет процента от общего итога (игнорируя текущие фильтры).
● Сравнение текущих продаж с продажами за предыдущий год/месяц.
● Расчет продаж для определенной категории продуктов, независимо от того, что выбрал пользователь в срезе.
Как работает CALCULATE()?
CALCULATE работает в три основных этапа:
1. Оценка выражения: Сначала CALCULATE оценивает Expression (обычно меру) в текущем контексте фильтра.
2. Модификация контекста фильтра: Затем CALCULATE применяет свои собственные фильтры (Filter1, Filter2, ...).
○ Если фильтр в CALCULATE относится к столбцу, который уже отфильтрован в текущем контексте, фильтр в CALCULATE переопределяет (заменяет) существующий фильтр.
○ Если фильтр в CALCULATE относится к столбцу, который не отфильтрован в текущем контексте, фильтр в CALCULATE добавляется к существующему контексту.
○ Функции, такие как ALL(), ALLEXCEPT(), REMOVEFILTERS(), могут быть использованы внутри CALCULATE для удаления фильтров.
3. Переоценка выражения: Выражение Expression переоценивается в новом, модифицированном контексте фильтра.
Примеры с AdventureWorks:
Магия CALCULATE
Давайте посмотрим, как CALCULATE преображает наши расчеты.
Пример 1: Продажи только для категории 'Bikes' (независимо от других фильтров)
Мы хотим меру, которая всегда показывает продажи велосипедов, даже если пользователь отфильтровал отчет по 'Clothing'.
Sales for Bikes =
CALCULATE (
[Total Sales], -- Наша базовая мера Total Sales
'Product'[Category] = "Bikes" -- Фильтр, который CALCULATE применит
)
● Что происходит: CALCULATE берет меру [Total Sales]. Затем, прежде чем ее вычислить, он удаляет любой существующий фильтр по столбцу Product[Category] и применяет новый фильтр: Product[Category] = "Bikes".
● Результат: Эта мера всегда будет показывать общие продажи велосипедов, независимо от того, что выбрано в срезах или других визуализациях по категории продукта.
Пример 2: Продажи за предыдущий год (Sales Last Year)
Это классический пример использования CALCULATE для временных сравнений.
Sales Last Year =
CALCULATE (
[Total Sales],
SAMEPERIODLASTYEAR ( 'Date'[Date] ) -- Функция времени, которая генерирует фильтр
)
● Что происходит:
SAMEPERIODLASTYEAR('Date'[Date]) генерирует таблицу дат, которая соответствует тому же периоду, что и текущий контекст фильтра, но смещенному на один год назад. CALCULATE берет эту таблицу дат и заменяет ею текущий контекст фильтра по дате.
● Результат: Если вы смотрите на продажи за июль 2007 года, Sales Last Year покажет продажи за июль 2006 года.
Пример 3: Процент от Общего Итога (Sales % of Grand Total)
Здесь нам нужно временно снять все фильтры, чтобы получить общий итог.
Sales % of Grand Total =
DIVIDE (
[Total Sales], -- Продажи текущего контекста
CALCULATE ( [Total Sales], ALL ( 'Product' ) ), -- Общие продажи, игнорируя фильтры по Product
BLANK()
)
● Что происходит:
CALCULATE ( [Total Sales], ALL ( 'Product' ) ) вычисляет [Total Sales], но при этом ALL('Product') удаляет все фильтры, которые были применены к таблице Product. Это позволяет получить общую сумму продаж по всем продуктам, независимо от того, какая категория или продукт выбраны в отчете.
● Результат:
Если вы смотрите на продажи 'Bikes', эта мера покажет процент продаж 'Bikes' от общих продаж всех продуктов.
CALCULATE — это невероятно мощный инструмент, который позволяет вам буквально "перемещаться" по контексту фильтра, создавая сложные и динамичные аналитические сценарии.