Переопределение контекста фильтрации функцией ALL

Переопределение контекста фильтрации функцией ALL

Рекомендация: в моделях со связями дополняйте ALL модификатором REMOVEFILTERS

Когда переопределяете контекст через ALL, добавляйте в тот же CALCULATE модификатор REMOVEFILTERS для этой же таблицы — так контекст сбрасывается надёжно:

CALCULATE( <выражение>, FILTER( ALL('factonlinesales'), <условие> ), REMOVEFILTERS('factonlinesales') )

Функция ALL в DAX является мощным инструментом для управления контекстом фильтрации в вычислениях. Её основное назначение — снимать применённые фильтры, позволяя выполнять агрегации по полному набору данных или заданному подмножеству. Однако при работе со связанными таблицами в реляционных моделях данных (таких как «звезда» или «снежинка») поведение ALL может оказаться неочевидным: по умолчанию она снимает фильтры только с указанной таблицы, не затрагивая связанные измерения. Это может приводить к неожиданным результатам, когда контекст фильтрации переопределяется не полностью. В таких случаях для полного сброса фильтров требуется явное указание с помощью модификатора REMOVEFILTERS.

Ниже представлены примеры того, как это может выглядеть на практике.

Пример для модели данных, построенной по схеме «звезда»

image-20251027-151752.png

Описание проблемы

Ниже представлена мера для расчета продаж за январь 2005 года:

Продажи за январь 2005 = CALCULATE ( SUMX ( 'factonlinesales', 'factonlinesales'[unitprice] ), FILTER ( ALL ( 'factonlinesales' ), 'factonlinesales'[datekey] <= DATE(2005, 01, 31) ) )

Результатом вычисления этой меры будет только строка за январь 2005 года:

image-20251027-151952.png

В данной ситуации при использовании ALL('factonlinesales') снимается фильтрация только с таблицы фактов, но не с связанных измерений. Из-за этого фильтры по датам, продуктам или клиентам сохраняются, и контекст фильтрации не переопределяется полностью. В результате на визуализации отображаются только данные за январь 2005 года вместо ожидаемых продаж за этот месяц во всех строках.

Обходное решение

Для корректного переопределения контекста фильтрации по связанным измерениям необходимо явно снять фильтры с таблицы factonlinesales при помощи модификатора REMOVEFILTERS:

Продажи за январь 2005 workaround = CALCULATE ( SUMX ( 'factonlinesales', 'factonlinesales'[unitprice] ), FILTER ( ALL ( 'factonlinesales' ), 'factonlinesales'[datekey] <= DATE(2005, 01, 31) ), REMOVEFILTERS(factonlinesales) )

Теперь для каждого месяца в визуализации отображаются продажи за январь 2005 года – без учёта текущего месяца в строке или внешних фильтров:

image-20251027-152241.png

Пример для модели данных, построенной по схеме «снежинка»

модель2.png

Описание проблемы

Ниже представлена мера для расчета продаж товаров класса Deluxe:

Продажи Deluxe = CALCULATE ( SUMX ( 'factonlinesales', 'factonlinesales'[unitprice] ), FILTER ( ALL ( 'dimproduct' ), dimproduct[classname] = "Deluxe" ) )

В этом случае для разных подкатегорий мы увидим разные значения при визуализации:

таблица3.png

Дело в том, что при использовании ALL('dimproduct') фильтрация снимается только с таблицы dimproduct, но не с связанных измерений. Из-за этого фильтры по подкатегориям сохраняются, и контекст фильтрации не переопределяется полностью. В результате на визуализации отображаются разные значения по строкам вместо ожидаемых продаж для класса Deluxe по всем подкатегориям.

Обходное решение

Для корректного переопределения контекста фильтрации по связанным измерениям необходимо явно снять фильтры с таблицы dimproduct при помощи модификатора REMOVEFILTERS:

Продажи Deluxe workaround = CALCULATE ( SUMX ( 'factonlinesales', 'factonlinesales'[unitprice] ), FILTER ( ALL ( 'dimproduct' ), dimproduct[classname] = "Deluxe" ), REMOVEFILTERS( 'dimproduct' ) )

Теперь для каждой подкатегории в визуализации будут отображаться продажи продуктов класса Deluxe – без учёта подкатегории или внешних фильтров:

таблица4.png

Пример: накопительный (нарастающий) итог с вложенным CALCULATE

Задача — посчитать нарастающий итог: внешний CALCULATE через FILTER(ALL('dimdate'), 'dimdate'[datekey] <= MAX('dimdate'[datekey])) должен расширять окно до текущей даты включительно. Сравним две меры — без REMOVEFILTERS и с ним.

Итог без REMOVEFILTERS = CALCULATE ( CALCULATE ( SUM ( 'factonlinesales'[salesamount] ), FILTER ( 'factonlinesales', 'factonlinesales'[salesamount] > 0 ) ), FILTER ( ALL ( 'dimdate' ), 'dimdate'[datekey] <= MAX ( 'dimdate'[datekey] ) ) ) Итог с REMOVEFILTERS = CALCULATE ( CALCULATE ( SUM ( 'factonlinesales'[salesamount] ), FILTER ( 'factonlinesales', 'factonlinesales'[salesamount] > 0 ) ), FILTER ( ALL ( 'dimdate' ), 'dimdate'[datekey] <= MAX ( 'dimdate'[datekey] ) ), REMOVEFILTERS ( 'dimdate' ) )
image (1).png

В мере «Итог без REMOVEFILTERS» при наличии вложенного CALCULATE с фильтром по таблице фактов одного FILTER(ALL('dimdate'), …) недостаточно, чтобы полностью переопределить контекст по 'dimdate' — итог считается в пределах текущего периода, а не нарастающим.

💡 Подсказка. Чтобы контекст по 'dimdate' сбрасывался полностью и итог накапливался, добавьте модификатор REMOVEFILTERS('dimdate') во внешний CALCULATE — как в мере «Итог с REMOVEFILTERS».


Смотрите также

ALL
REMOVEFILTERS