Шпаргалка по Power BI
Последнее обновление
Меры, столбцы и таблицы
Мера вычисляется для каждой ячейки визуального элемента; вычисляемый столбец вычисляется один раз для каждой строки и хранится в модели.
| Что делает | DAX |
|---|---|
| Создать меру | Total Sales = SUM ( Sales[Amount] ) |
| Создать вычисляемый столбец (одно значение на строку) | Line Total = Sales[Quantity] * Sales[Unit Price] |
| Создать вычисляемую таблицу | Top Customers = TOPN ( 10, Customer, [Total Sales] ) |
| Сослаться на столбец: имя таблицы, затем столбец в квадратных скобках | Sales[Amount] |
| Взять в кавычки имя таблицы, в котором есть пробел или которое является зарезервированным словом | 'Date'[Date] |
| Сослаться на меру: только квадратные скобки | [Total Sales] |
| Использовать меру внутри другой меры | Average Price = DIVIDE ( [Total Sales], [Total Units] ) |
Функции агрегации
Каждая из них сводит столбец в текущем контексте фильтра.
| Что делает | DAX |
|---|---|
| Сложить значения столбца | SUM ( Sales[Amount] ) |
| Среднее по столбцу | AVERAGE ( Sales[Amount] ) |
| Наименьшее значение | MIN ( Sales[Order Date] ) |
| Наибольшее значение | MAX ( Sales[Order Date] ) |
| Посчитать строки таблицы | COUNTROWS ( Sales ) |
| Посчитать непустые значения столбца | COUNT ( Sales[Amount] ) |
| Посчитать уникальные значения | DISTINCTCOUNT ( Sales[Customer Key] ) |
| Безопасное деление: пустое значение вместо ошибки, когда знаменатель равен 0 | DIVIDE ( [Total Sales], [Total Units] ) |
| Деление со значением, которое показывается, когда знаменатель равен 0 | DIVIDE ( [Profit], [Total Sales], 0 ) |
Итераторы (функции X)
Они проходят по таблице строка за строкой, вычисляют выражение для каждой строки, а затем агрегируют результаты.
| Что делает | DAX |
|---|---|
| Умножить в каждой строке, затем сложить | SUMX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Среднее от результата по каждой строке | AVERAGEX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Наибольший результат по строкам | MAXX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| Среднее значение меры по клиентам | AVERAGEX ( VALUES ( Customer[Customer Key] ), [Total Sales] ) |
| Использовать в выражении столбец связанной таблицы | SUMX ( Sales, Sales[Quantity] * RELATED ( Product[Unit Cost] ) ) |
| Посчитать строки, которые проходят условие | COUNTROWS ( FILTER ( Sales, Sales[Quantity] >= 3 ) ) |
| Ранжировать каждый продукт по мере | RANKX ( ALL ( Product[Product] ), [Total Sales] ) |
| Ранг без пропусков после равных значений (1, 1, 2) | RANKX ( ALL ( Product[Product] ), [Total Sales], , DESC, DENSE ) |
| Объединить значения в один текст | CONCATENATEX ( VALUES ( Product[Category] ), Product[Category], ", " ) |
CALCULATE и функции фильтров
CALCULATE вычисляет выражение с изменёнными фильтрами. Фильтр на тот же столбец заменяет старый; фильтры на разные столбцы объединяются через AND.
| Что делает | DAX |
|---|---|
| Фильтр по одному значению | CALCULATE ( [Total Sales], Product[Category] = "Bikes" ) |
| Фильтр по списку значений | CALCULATE ( [Total Sales], Product[Color] IN { "Red", "Blue" } ) |
| Два фильтра (AND) | CALCULATE ( [Total Sales], Product[Color] = "Red", Store[Country] = "Spain" ) |
| OR по двум столбцам | CALCULATE ( [Total Sales], FILTER ( ALL ( Product[Color], Product[Brand] ), Product[Color] = "Red" || Product[Brand] = "Contoso" ) ) |
| Фильтр по мере | CALCULATE ( [Total Sales], FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| Сохранить текущий фильтр и пересечь с ним | CALCULATE ( [Total Sales], KEEPFILTERS ( Product[Color] IN { "Red", "Blue" } ) ) |
| Снять фильтры со столбца | CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) |
| Снять все фильтры с таблицы | CALCULATE ( [Total Sales], ALL ( Product ) ) |
| Снять все фильтры с таблицы, кроме некоторых столбцов | CALCULATE ( [Total Sales], ALLEXCEPT ( Store, Store[Country] ) ) |
| Сохранить выбор в срезах, но убрать строки самого визуального элемента | CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) |
| Использовать неактивную связь | CALCULATE ( [Total Sales], USERELATIONSHIP ( Sales[Ship Date], 'Date'[Date] ) ) |
| Пропустить фильтр в обе стороны для одной меры | CALCULATE ( COUNTROWS ( Customer ), CROSSFILTER ( Sales[Customer Key], Customer[Customer Key], BOTH ) ) |
| Фильтр по таблице, с которой нет связи | CALCULATE ( [Total Sales], TREATAS ( VALUES ( Budget[Category] ), Product[Category] ) ) |
Логика операций со временем
Для этих функций нужна таблица дат: одна строка на каждый день, без пропусков, отмеченная как таблица дат.
| Что делает | DAX |
|---|---|
| С начала года | TOTALYTD ( [Total Sales], 'Date'[Date] ) |
| С начала года, финансовый год заканчивается 30 июня | TOTALYTD ( [Total Sales], 'Date'[Date], "6/30" ) |
| С начала года внутри CALCULATE | CALCULATE ( [Total Sales], DATESYTD ( 'Date'[Date] ) ) |
| С начала квартала | TOTALQTD ( [Total Sales], 'Date'[Date] ) |
| С начала месяца | TOTALMTD ( [Total Sales], 'Date'[Date] ) |
| Тот же период прошлого года | CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) |
| Сдвинуть даты на интервал (здесь на месяц назад) | CALCULATE ( [Total Sales], DATEADD ( 'Date'[Date], -1, MONTH ) ) |
| Весь предыдущий месяц | CALCULATE ( [Total Sales], PREVIOUSMONTH ( 'Date'[Date] ) ) |
| Весь период год назад | CALCULATE ( [Total Sales], PARALLELPERIOD ( 'Date'[Date], -1, YEAR ) ) |
| Последние 12 месяцев до последней видимой даты | CALCULATE ( [Total Sales], DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -12, MONTH ) ) |
| Фиксированный диапазон дат | CALCULATE ( [Total Sales], DATESBETWEEN ( 'Date'[Date], DATE ( 2025, 1, 1 ), DATE ( 2025, 3, 31 ) ) ) |
Частые шаблоны мер
Скопируйте, затем переименуйте таблицы и столбцы под свою модель.
| Что делает | DAX |
|---|---|
| Доля от всех категорий | Category % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) ) |
| Доля от того, что оставили срезы | Visible % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) ) |
| Рост год к году | YoY % = VAR LastYear = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN DIVIDE ( [Total Sales] - LastYear, LastYear ) |
| Нарастающий итог за всё время | Running Total = CALCULATE ( [Total Sales], FILTER ( ALL ( 'Date'[Date] ), 'Date'[Date] <= MAX ( 'Date'[Date] ) ) ) |
| Скользящее среднее за 7 дней (по дням с продажами) | Sales 7 Day Avg = AVERAGEX ( DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -7, DAY ), [Total Sales] ) |
| Показать значение только для первых 5 | Top 5 Sales = IF ( RANKX ( ALLSELECTED ( Product[Product] ), [Total Sales] ) <= 5, [Total Sales] ) |
| Посчитать клиентов выше порога | Big Customers = COUNTROWS ( FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| Сделать так, чтобы итог был суммой своих строк | Bonus Total = SUMX ( VALUES ( Product[Category] ), [Bonus] ) |
| Показать значение только на одном уровне матрицы | Category Rank = IF ( ISINSCOPE ( Product[Category] ), RANKX ( ALL ( Product[Category] ), [Total Sales] ) ) |
| Остаток на конец периода: последняя дата, у которой есть значение | Closing Units = CALCULATE ( SUM ( Inventory[Units] ), LASTNONBLANK ( 'Date'[Date], CALCULATE ( SUM ( Inventory[Units] ) ) ) ) |
Логические и информационные функции
Для условий и для вопросов о том, что содержит контекст фильтра.
| Что делает | DAX |
|---|---|
| Одно условие | IF ( [Total Sales] > 1000, "High", "Low" ) |
| Несколько значений одного выражения | SWITCH ( Store[Country], "Spain", "ES", "Portugal", "PT", "Other" ) |
| Диапазоны, проверяются сверху вниз | SWITCH ( TRUE (), [Total Sales] >= 10000, "A", [Total Sales] >= 1000, "B", "C" ) |
| AND и OR | IF ( Sales[Quantity] > 2 && Sales[Amount] > 50, "Big", "Small" ) |
| Значение пустое? | ISBLANK ( [Total Sales] ) |
| Первое непустое значение | COALESCE ( [Total Sales], 0 ) |
| Оставляет ли фильтр ровно одно значение? | HASONEVALUE ( Product[Category] ) |
| Это единственное значение или значение по умолчанию | SELECTEDVALUE ( Product[Category], "All categories" ) |
| Сгруппирована ли эта строка визуального элемента по столбцу? | ISINSCOPE ( Product[Category] ) |
| Вернуть пустое значение | BLANK () |
Текстовые функции
Оператор & объединяет текст; FORMAT превращает число или дату в текст.
| Что делает | DAX |
|---|---|
| Объединить текст | Customer[First Name] & " " & Customer[Last Name] |
| Отформатировать число | FORMAT ( [Total Sales], "#,0.00" ) |
| Отформатировать дату | FORMAT ( 'Date'[Date], "mmm yyyy" ) |
| Первые символы | LEFT ( Product[Code], 3 ) |
| Символы с заданной позиции | MID ( Product[Code], 4, 2 ) |
| Длина | LEN ( Product[Name] ) |
| Верхний регистр | UPPER ( Store[City] ) |
| Убрать лишние пробелы | TRIM ( Customer[Name] ) |
| Заменить текст | SUBSTITUTE ( Customer[Phone], " ", "" ) |
| Позиция текста без учёта регистра (0, если не найден) | SEARCH ( "pro", Product[Name], 1, 0 ) |
Функции даты
Внутри даты хранятся как числа, поэтому их можно вычитать и получать число дней.
| Что делает | DAX |
|---|---|
| Сегодняшняя дата | TODAY () |
| Собрать дату | DATE ( 2025, 12, 31 ) |
| Год даты | YEAR ( 'Date'[Date] ) |
| Номер месяца | MONTH ( 'Date'[Date] ) |
| День недели, понедельник равен 1 | WEEKDAY ( 'Date'[Date], 2 ) |
| Номер недели, недели начинаются с понедельника | WEEKNUM ( 'Date'[Date], 2 ) |
| Последний день месяца | EOMONTH ( 'Date'[Date], 0 ) |
| Тот же день месяцем раньше | EDATE ( 'Date'[Date], -1 ) |
| Число дней между двумя датами | DATEDIFF ( Sales[Order Date], Sales[Ship Date], DAY ) |
| Таблица дат из фиксированных дат | CALENDAR ( DATE ( 2024, 1, 1 ), DATE ( 2025, 12, 31 ) ) |
| Таблица дат из дат в модели | CALENDARAUTO () |
Связи и поиск значений
RELATED идёт по связи со стороны «многие» к стороне «один».
| Что делает | DAX |
|---|---|
| Значение со стороны «один» (в столбце таблицы Sales) | RELATED ( Product[Category] ) |
| Строки стороны «многие» для текущей строки (в столбце таблицы Customer) | COUNTROWS ( RELATEDTABLE ( Sales ) ) |
| Найти значение без связи | LOOKUPVALUE ( Product[Price], Product[SKU], Sales[SKU] ) |
| Путь «родитель и потомок» (для иерархий и безопасности на уровне строк) | PATH ( Employee[Employee ID], Employee[Manager ID] ) |
| Пользователь, который вошёл в систему, для динамической безопасности на уровне строк | USERPRINCIPALNAME () |
Табличные функции
Они возвращают таблицы: используйте их в вычисляемой таблице, внутри CALCULATE или в итераторе.
| Что делает | DAX |
|---|---|
| Уникальные значения в текущем фильтре | VALUES ( Product[Category] ) |
| Строки, которые проходят условие | FILTER ( Product, Product[Price] > 100 ) |
| Первые N строк по мере | TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) |
| Сгруппировать по столбцам и добавить меры | SUMMARIZECOLUMNS ( Product[Category], "Sales", [Total Sales] ) |
| Добавить столбец в таблицу | ADDCOLUMNS ( VALUES ( Product[Category] ), "Sales", [Total Sales] ) |
| Выбрать и переименовать столбцы | SELECTCOLUMNS ( Customer, "Name", Customer[Name], "City", Customer[City] ) |
| Список чисел | GENERATESERIES ( 1, 10, 1 ) |
| Все сочетания строк двух таблиц | CROSSJOIN ( VALUES ( 'Date'[Year] ), VALUES ( Product[Category] ) ) |
| Поставить одну под другой две таблицы с одинаковыми столбцами | UNION ( 'Sales 2024', 'Sales 2025' ) |
Переменные
VAR даёт имя шагу и вычисляет его один раз; RETURN возвращает результат.
| Что делает | DAX |
|---|---|
| Одна переменная | Margin % = VAR Revenue = [Total Sales] RETURN DIVIDE ( Revenue - [Total Cost], Revenue ) |
| Несколько переменных | Sales vs LY = VAR CY = [Total Sales] VAR PY = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN CY - PY |
| Таблица в переменной | Top 5 Total = VAR Top5 = TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) RETURN CALCULATE ( [Total Sales], Top5 ) |
Шаги Power Query (M)
Power Query приводит данные в нужный вид до загрузки. Это формулы M, которые стоят за часто используемыми кнопками.
| Что делает | M |
|---|---|
| Оставить подходящие строки | Table.SelectRows(Source, each [Status] = "Paid") |
| Удалить столбцы | Table.RemoveColumns(Source, {"Notes", "Temp"}) |
| Задать типы столбцов | Table.TransformColumnTypes(Source, {{"Amount", type number}, {"Date", type date}}) |
| Переименовать столбец | Table.RenameColumns(Source, {{"amt", "Amount"}}) |
| Добавить столбец | Table.AddColumn(Source, "Total", each [Quantity] * [Price], type number) |
| Объединить два запроса (join) | Table.NestedJoin(Sales, {"ProductID"}, Products, {"ProductID"}, "Product", JoinKind.LeftOuter) |
| Добавить запросы (одну таблицу под другой) | Table.Combine({Sales2024, Sales2025}) |
| Отменить свёртывание столбцов (столбцы в строки) | Table.UnpivotOtherColumns(Source, {"Product"}, "Month", "Amount") |
| Сгруппировать и агрегировать | Table.Group(Source, {"Category"}, {{"Sales", each List.Sum([Amount]), type number}}) |
| Заменить ошибки значением | Table.ReplaceErrorValues(Source, {{"Amount", 0}}) |
В этой шпаргалке по Power BI на одной странице собран DAX, который пишут чаще всего: агрегации, итераторы X, CALCULATE и функции, которые меняют фильтры, логика операций со временем, текстовые функции и функции дат, а также шаблоны мер, которые можно скопировать: доля от итога, рост год к году и нарастающий итог.
В примерах используется модель продаж с таблицами Sales, Product, Customer и 'Date'; переименуйте их под свою модель. Весь DAX здесь разобран движком, на котором работает курс Coddy по Power BI: там его можно писать в рабочей области Power BI прямо в браузере и сразу получать проверку.
Частые вопросы о шпаргалке по Power BI
Эта шпаргалка по Power BI бесплатная?
Да. Читайте её здесь или добавьте в закладки, регистрация не нужна.
Чем мера отличается от вычисляемого столбца?
Вычисляемый столбец вычисляется один раз для каждой строки при обновлении и хранится в модели, поэтому по нему можно фильтровать срезом. Мера вычисляется для каждой ячейки визуального элемента, с фильтрами этой ячейки, и ничего не хранит. Итоги и соотношения лучше делать мерами.
Что делает CALCULATE?
Вычисляет выражение с изменёнными фильтрами: добавляет, заменяет или снимает фильтры, а затем считает результат. Почти всё в DAX, что сложнее простых итогов, строится на CALCULATE с правильными аргументами фильтров.
Зачем использовать DIVIDE вместо оператора /?
DIVIDE возвращает пустое значение (или значение, которое вы выберете), когда знаменатель равен нулю или пуст. Оператор / в таком случае возвращает бесконечность или значение ошибки, и оно появляется в визуальных элементах.Нужна ли таблица дат для логики операций со временем?
TOTALYTD и SAMEPERIODLASTYEAR нужна таблица с одной строкой на каждый день, без пропусков и с полными годами, связанная с таблицами фактов и отмеченная как таблица дат.Работает ли этот DAX в Power Pivot для Excel и в Analysis Services?
Язык DAX общий, поэтому почти всё работает и там. Некоторые новые функции сначала появляются в Power BI.
Где потренироваться в DAX?
В курсе Coddy по Power BI: каждый урок открывает рабочую область Power BI в браузере и проверяет вашу меру на данных урока и на их скрытых копиях.