Курс аналітики даних · Урок 8 з 9 · 15 липня 2026

DAX для початківців: міри, CALCULATE та контекст

Ви побудували модель даних, налаштували зв’язки — і вперлися в стелю. Стандартні агрегати Power BI показують суму чи кількість, але не вміють порахувати «продажі за цей рік порівняно з минулим» або «частку міста в загальній виручці». Для таких розрахунків потрібен DAX (Data Analysis Expressions) — мова формул Power BI.

Power BI·8 хв читання
DAX для початківців: міри, CALCULATE та контекст

DAX лякає новачків не синтаксисом, а поняттям контексту: одна й та сама міра повертає різні числа в різних клітинках візуала. Щойно ви зрозумієте, як працює контекст фільтра, 80% «магії» DAX стане передбачуваною логікою.

Це урок 8 безкоштовного курсу аналітики даних. Ми розберемо різницю між колонками та мірами, функції SUM і SUMX, головну функцію CALCULATE та базовий time intelligence — усе на знайомій моделі магазину з таблицями orders, customers, products і order_items.

Що таке DAX і навіщо він потрібен

DAX — це мова формул для Power BI, Power Pivot в Excel та Analysis Services. Зовні вона схожа на формули Excel: є функції, дужки, оператори. Але принципова різниця в тому, що DAX працює не з окремими клітинками, а з колонками й таблицями цілком.

У Power BI DAX використовують для трьох речей: обчислюваних колонок, мір і обчислюваних таблиць. У цьому уроці зосередимося на перших двох — саме вони потрібні в 95% реальних звітів.

Важливий нюанс: коли ви просто перетягуєте числову колонку у візуал, Power BI створює неявну міру (автоматичний SUM або COUNT). Для навчальних звітів це прийнятно, але в робочих моделях краще писати явні міри: їх можна перевикористовувати, форматувати й посилатися на них в інших формулах.

Обчислювані колонки vs міри

Це перший вибір, який ви робите перед написанням формули. Обчислювана колонка додає нове значення в кожен рядок таблиці й зберігається в моделі. Міра нічого не зберігає — вона обчислюється «на льоту» в момент, коли ви кладете її у візуал.

КритерійОбчислювана колонкаМіра
Коли обчислюєтьсяПід час оновлення данихПід час взаємодії зі звітом
Де зберігаєтьсяУ моделі, займає пам’ятьНе зберігається
Контекст за замовчуваннямКонтекст рядкаКонтекст фільтра
Типове використанняКатегорія, прапорець, ключ для зв’язкуСуми, середні, частки, порівняння періодів
Вплив на розмір файлуЗбільшуєМайже не впливає

Практичне правило: якщо результат потрібен для агрегації у візуалі — пишіть міру. Колонку створюйте лише тоді, коли значення потрібне як вісь, зріз або умова на рівні рядка. Приклад корисної колонки — рік замовлення:

Рік замовлення = YEAR(orders[order_date])

А ось сума продажів має бути мірою, а не колонкою:

Сума продажів = SUM(orders[amount])

Контекст: чому одна міра дає різні числа

Контекст — це набір умов, за яких обчислюється формула. У DAX є два типи контексту, і їх плутання — джерело більшості помилок початківців.

Контекст рядка

Контекст рядка означає «формула бачить один поточний рядок таблиці». Він автоматично існує в обчислюваних колонках: коли ви пишете YEAR(orders[order_date]), Power BI проходить рядок за рядком і для кожного бере його власну дату. У мірах контексту рядка за замовчуванням немає — його створюють функції-ітератори, як-от SUMX.

Контекст фільтра

Контекст фільтра — це всі фільтри, що діють на клітинку візуала: значення на осях, зрізи, фільтри сторінки, виділення в сусідніх діаграмах. Якщо міра «Сума продажів» стоїть у рядку «Київ» таблиці за містами, Power BI спершу відфільтрує замовлення клієнтів із Києва, а вже потім підсумує amount.

Саме тому та сама міра показує 50 000 у рядку «Київ», 30 000 у рядку «Львів» і 200 000 у підсумку. Формула одна — контекст фільтра різний. Коли міра повертає «дивне» число, перше питання завжди однакове: які фільтри діють на цю клітинку?

SUM і SUMX: агрегати та ітератори

SUM просто підсумовує одну колонку в поточному контексті фільтра. Але що робити, коли потрібно спершу перемножити значення в кожному рядку? У таблиці order_items є кількість qty, а ціна лежить у пов’язаній таблиці products. Написати SUM(order_items[qty] * products[price]) не вийде — SUM приймає лише одну колонку.

Тут потрібен ітератор SUMX. Він проходить таблицю рядок за рядком (створює контекст рядка), обчислює вираз для кожного рядка і підсумовує результати:

Виручка за позиціями =
SUMX(
    order_items,
    order_items[qty] * RELATED(products[price])
)

Функція RELATED підтягує ціну з таблиці products через зв’язок, який ви налаштували в уроці про моделювання. Аналогічно працюють AVERAGEX, MINX, MAXX і COUNTX — усі вони ітератори з тим самим принципом «таблиця + вираз».

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

CALCULATE обчислює вираз у зміненому контексті фільтра. Це єдина функція, яка вміє переписувати фільтри, тому її називають серцем DAX. Синтаксис простий: перший аргумент — вираз (зазвичай міра), далі — один або кілька фільтрів.

Продажі завершені =
CALCULATE(
    [Сума продажів],
    orders[status] = "completed"
)

Ця міра завжди рахує тільки завершені замовлення — незалежно від того, у якому візуалі стоїть. Фільтр orders[status] = "completed" додається до наявного контексту, а якщо у контексті вже був інший фільтр по status, він замінюється новим.

CALCULATE + FILTER для складних умов

Простий фільтр у CALCULATE порівнює колонку з константою. Коли умова складніша — наприклад, порівняння з мірою або кілька колонок в одній умові — використовуйте FILTER:

Продажі великих замовлень =
CALCULATE(
    [Сума продажів],
    FILTER(
        orders,
        orders[amount] > 1000 && orders[status] = "completed"
    )
)

FILTER повертає відфільтровану таблицю, яку CALCULATE застосовує як фільтр. Майте на увазі: FILTER — ітератор, і на великих таблицях він працює повільніше за простий фільтр-предикат. Якщо умову можна записати без FILTER — запишіть без нього.

ALL: знімаємо фільтри й рахуємо частки

Функція ALL робить протилежне — прибирає фільтри з таблиці або колонки. Класичне застосування — відсоток від загального. У таблиці за містами кожен рядок фільтрує продажі свого міста, а для частки потрібен ще й загальний підсумок без цього фільтра:

% від усіх міст =
DIVIDE(
    [Сума продажів],
    CALCULATE([Сума продажів], ALL(customers[city]))
)

Чисельник рахується у поточному контексті (одне місто), а знаменник — у контексті, де фільтр по місту знято. DIVIDE замість оператора «/» захищає від ділення на нуль. Споріднені функції: ALLSELECTED (враховує зрізи, але ігнорує осі візуала) та ALLEXCEPT (знімає всі фільтри, крім указаних).

Time intelligence: порівнюємо періоди

Функції часового аналізу — головна причина, чому в моделі потрібна календарна таблиця (ми створювали її в попередньому уроці). Вони працюють коректно, лише коли отримують безперервну колонку дат, позначену як таблиця дат.

Дві найуживаніші функції. TOTALYTD накопичує значення з початку року до поточної дати контексту:

Продажі YTD =
TOTALYTD([Сума продажів], 'Календар'[Date])

SAMEPERIODLASTYEAR зсуває контекст дат на рік назад — так порівнюють період із аналогічним торік:

Продажі рік тому =
CALCULATE(
    [Сума продажів],
    SAMEPERIODLASTYEAR('Календар'[Date])
)

Приріст рік до року % =
DIVIDE(
    [Сума продажів] - [Продажі рік тому],
    [Продажі рік тому]
)

Зверніть увагу: міри посилаються на інші міри. Це нормальна практика — будуйте прості «базові» міри, а складні збирайте з них, як із цеглинок. Так формули легше читати й виправляти.

Коли освоїте ці дві функції, погляньте на споріднені: DATESYTD, PREVIOUSMONTH, DATEADD і DATESINPERIOD для ковзних періодів. Усі вони працюють за тим самим принципом — повертають набір дат, який CALCULATE підставляє в контекст фільтра замість поточного.

Поширені помилки

  • Колонка замість міри. Обчислювані колонки для сум і часток роздувають модель і не реагують на фільтри так, як ви очікуєте. Агрегати — завжди мірами.
  • SUM там, де потрібен SUMX. Якщо перед підсумовуванням треба щось перемножити чи обчислити в кожному рядку — це робота ітератора, а не простого SUM.
  • Time intelligence без календарної таблиці. TOTALYTD і SAMEPERIODLASTYEAR по колонці orders[order_date] з пропусками дат дають неправильні результати. Створіть календар і позначте його як таблицю дат.
  • FILTER по всій таблиці без потреби. FILTER(orders, orders[status] = "completed") повільніший за простий предикат orders[status] = "completed". FILTER лишайте для умов, які інакше не записати.
  • Забутий DIVIDE. Оператор «/» падає з помилкою або показує «нескінченність» при діленні на нуль. DIVIDE повертає порожнє значення або заданий вами запасний результат.
  • Ігнорування контексту. Якщо міра показує однакове число в усіх рядках — найчастіше ви зняли фільтр через ALL там, де не треба, або фільтруєте не ту таблицю.

FAQ

Чим DAX відрізняється від формул Excel?

Синтаксис схожий, але Excel працює з клітинками та діапазонами, а DAX — з колонками й таблицями. У DAX немає поняття «клітинка A1»: результат завжди залежить від контексту фільтра, тобто від того, де саме у звіті стоїть формула.

Чи потрібно вчити всі функції DAX?

Ні. Для впевненого старту досить SUM, SUMX, CALCULATE, FILTER, ALL, DIVIDE, RELATED і двох-трьох функцій time intelligence. Це покриває більшість задач бізнес-звітності. Решту функцій ви додаватимете поступово, коли з’являться конкретні задачі.

Де зберігати міри, щоб не загубитися?

Створіть порожню таблицю (наприклад, через «Введення даних»), назвіть її «_Міри» й переносьте туди всі міри. Так вони лежатимуть в одному місці на панелі полів, а не будуть розкидані по таблицях фактів і вимірів.

Чому моя міра повертає порожнє значення?

Найчастіші причини: контекст фільтра відсіяв усі рядки (наприклад, комбінація зрізів без даних), розірваний зв’язок між таблицями або фільтр у CALCULATE, який суперечить наявному контексту. Перевірте зв’язки в поданні моделі й тимчасово приберіть фільтри з візуала.

Що далі

Ви освоїли фундамент DAX: тепер ви знаєте, коли писати колонку, а коли міру, як CALCULATE змінює контекст фільтра і як порівнювати періоди через time intelligence. Потренуйтеся: створіть у своїй моделі магазину міри «Виручка», «% від загального» та «Приріст рік до року» і покладіть їх на дашборд.

Якщо міри повертають дивні числа — проблема майже завжди в моделі, тож поверніться до попереднього уроку «Моделювання даних у Power BI: зв’язки та схема “зірка”» і перевірте зв’язки та календарну таблицю.

А в наступному, фінальному уроці зберемо все докупи: «Як стати дата-аналітиком з нуля: покроковий план» — навички, портфоліо та план навчання на 90 днів. Повний перелік уроків — на сторінці курсу аналітики даних.

Це урок 8 з 9 курсу аналітики даних.

Уроки виходять щодня о 09:30 — програма і навігація на сторінці курсу.

Поділитися статтею