Power BI календари: ошибки работы с неделями и пользовательскими датами | AiManual
AiManual Logo Ai / Manual.
10 Апр 2026 Гайд

Ловушки и решения при работе с пользовательскими календарями в Power BI и табличных моделях

Глубокий разбор ошибок при работе с календарями в Power BI. Как настроить таблицу дат, избежать интерференции календарей и правильно считать недели.

Календари в Power BI: тихий ужас аналитика

Вы строите отчет по недельным продажам. Все выглядит отлично, пока не замечаете, что сумма за последнюю неделю января не сходится с данными из ERP. Вы проверяете формулы, пересчитываете в Excel - все верно. А в Power BI - нет. Знакомо?

Проблема не в ваших навыках DAX. Проблема в календарях. Точнее, в их конфликте. Power BI любит грегорианский календарь. Ваш бизнес - нет. Производственные недели, 4-4-5 периоды, фискальные годы - все это ломает стандартную временную аналитику.

И когда вы создаете пользовательскую таблицу дат, начинается интерференция. Две таблицы дат борются за отношения с фактами. Меры DAX начинают возвращать не то, путаются в контекстах. Отчеты врут.

Я расскажу, как этого избежать. Не поверхностно, а с деталями, которые понимают только те, кто уже наступил на эти грабли.

Грегорианский календарь против бизнеса: кто кого?

Power BI по умолчанию использует стандартный календарь. Год начинается 1 января, недели с понедельника или воскресенья (зависит от локали). Для бизнес-аналитики это часто бесполезно.

Потому что бизнес живет по своим циклам:

  • Производственные недели: с понедельника по воскресенье? Или с воскресенья по субботу? А может, среда-вторник? Да, бывает и так.
  • Финансовые периоды: 4-4-5 (два месяца по 4 недели, один - 5). Или 5-4-4. Или 13 периодов по 28 дней. Стандартные месяцы не подходят.
  • ISO недели: неделя начинается с понедельника, первая неделя года - та, где есть четверг. Это международный стандарт, но Power BI не использует его по умолчанию.

Вы пытаетесь добавить столбец ISOWeekNum в таблицу дат. И все равно получаете не те числа. Почему? Потому что функции DAX типа WEEKNUM используют разные системы нумерации. А если у вас свой календарь - вообще беда.

Таблица дат: 5 ошибок, которые делают все

Создаете таблицу дат через CALENDAR или CALENDARAUTO? Уже ошибка. Нет, эти функции хороши для базового календаря. Но для пользовательского - нет.

Вот как НЕ надо делать:

DateTable = 
ADDCOLUMNS (
    CALENDAR ( DATE ( 2020, 1, 1 ), DATE ( 2025, 12, 31 ) ),
    "Year", YEAR ( [Date] ),
    "Month", MONTH ( [Date] ),
    "WeekNum", WEEKNUM ( [Date], 2 ) -- ISO? Нет, это система 2, но не совсем ISO.
)

Эта таблица даст вам недели, но они не совпадут с ISO. Система 2 в WEEKNUM - это недели, начинающиеся с понедельника, но первая неделя года - та, где 1 января. В ISO первая неделя - где есть четверг. Разница может быть в несколько дней.

Другие ошибки:

  1. Несколько таблиц дат: одна для стандартного календаря, другая для производственного. Они конфликтуют за отношения с фактами. Power BI может использовать не ту, что нужно.
  2. Отсутствие ключей для связи: вы связываете таблицу фактов с датой, но у вас есть еще периоды. Нужен составной ключ? Иногда да, но чаще - отдельное отношение.
  3. Использование автоматических временных интеллект-функций: они работают только с одной таблицей дат, которую вы пометили как date table. Если у вас две календарных системы - они сломаются.
  4. Неправильная сортировка: текстовые поля типа "Январь 2026" не отсортируются по хронологии без числового столбца сортировки.
  5. Пропуск дат: в производственном календаре есть только рабочие дни. Но если в фактах есть продажи на выходные? Они не попадут в отчет.

Одна таблица дат на все календари: правильная архитектура

Не создавайте несколько таблиц дат. Создайте одну, но с полями для всех календарных систем. Это сложнее, но работает.

1 Определите диапазон дат

Возьмите минимальную и максимальную дату из всех фактовых таблиц. Добавьте запас в пару лет вперед и назад. Не используйте CALENDARAUTO - он берет даты из текущего контекста, а если данных еще нет, он ошибется.

StartDate = DATE ( 2020, 1, 1 )
EndDate = DATE ( 2030, 12, 31 )
Dates = CALENDAR ( StartDate, EndDate )

2 Добавьте столбцы для каждого календаря

Создайте отдельные столбцы для грегорианского календаря, ISO недель, производственного календаря. Используйте DAX или лучше - заранее подготовленную таблицу в источнике данных. DAX может тормозить на больших объемах.

Пример для ISO недель:

DatesWithISO = 
ADDCOLUMNS (
    Dates,
    "ISO Year", YEAR ( [Date] ) - IF ( WEEKDAY ( [Date], 2 ) < 4, 0, 1 ) + IF ( WEEKNUM ( [Date], 21 ) = 1, 1, 0 ), -- Упрощенная логика, лучше использовать ISOWEEKNUM
    "ISO Week Number", ISOWEEKNUM ( [Date] ) -- В DAX есть ISOWEEKNUM с 2023 года? Проверим. На 2026 год - да, функция есть.
)
💡
Функция ISOWEEKNUM появилась в DAX относительно недавно. Если вы используете старую версию Power BI, возможно, ее нет. Тогда придется писать сложную логику самостоятельно. К счастью, на 2026 год она уже стандарт.

Для производственного календаря вам понадобится таблица с рабочими днями и периодами. Ее лучше загрузить из внешнего источника (Excel, базы данных). Затем связать с таблицей дат по полной дате.

3 Настройте отношения

Свяжите таблицу фактов с таблицей дат по полной дате (date). Это основное отношение. Для производственного календаря создайте отдельную таблицу периодов (Periods) с полями PeriodKey, StartDate, EndDate, PeriodName. Затем свяжите ее с фактами через вспомогательную таблицу связи.

Не создавайте прямое отношение фактов с Periods по диапазону дат - DAX не поддерживает отношения по диапазону. Вместо этого используйте технику с bridge table или меры с FILTER.

Подробнее о сложных отношениях я писал в статье про финансовые модели и Star Schema.

DAX-меры: как считать в разных календарях

Создали таблицу дат. Теперь нужно написать меры, которые будут правильно работать в контексте каждого календаря.

Стандартная мера суммы продаж:

Total Sales = SUM ( Sales[Amount] )

Чтобы считать продажи по ISO неделям, просто используйте столбец ISO Week Number в визуалах. Но если вам нужна мера, которая возвращает сумму за текущую ISO неделю (в контексте фильтра), то это уже сложнее.

Не пишите так:

Sales ISO Week = 
CALCULATE (
    [Total Sales],
    FILTER (
        Dates,
        Dates[ISO Week Number] = SELECTEDVALUE ( Dates[ISO Week Number] )
    )
)

Это вызовет циклические зависимости или будет работать медленно. Вместо этого используйте функцию VALUES и отношение по дате.

Правильно:

Sales ISO Week = 
CALCULATE (
    [Total Sales],
    KEEPFILTERS ( Dates[ISO Week Number] )
)

KEEPFILTERS гарантирует, что фильтр по ISO неделе применяется правильно, не удаляя другие контексты.

Для производственного календаря, где нет прямого отношения, используйте меры с пересечением дат:

Sales Production Period = 
CALCULATE (
    [Total Sales],
    FILTER (
        Sales,
        Sales[Date] >= MIN ( ProductionPeriods[StartDate] )
            && Sales[Date] <= MAX ( ProductionPeriods[EndDate] )
    )
)

Эта мера будет работать, но может быть медленной на больших данных. Если возможно, создайте bridge table, которая связывает каждую дату с периодом, и установите отношение через нее.

Интерференция календарей: когда два календаря дерутся

Интерференция возникает, когда у вас несколько календарных систем и они конфликтуют в контексте фильтрации. Например, вы фильтруете по ISO неделе 1 2026 года и одновременно по производственному периоду P1. Эти периоды могут пересекаться только частично.

Power BI применяет оба фильтра к таблице дат. Если у вас одна таблица дат, то фильтры применяются к разным столбцам одной таблицы - это нормально. Но если у вас две отдельные таблицы дат, связанные с фактами, то Power BI попытается использовать оба отношения, и результат будет непредсказуемым.

Решение: используйте одну таблицу дат с разными атрибутами. Если все же нужны отдельные таблицы (например, для гибкости), то управляйте отношениями с помощью USERELATIONSHIP в мерах.

Sales Gregorian = 
CALCULATE (
    [Total Sales],
    USERELATIONSHIP ( Sales[Date], GregorianDates[Date] )
)

Sales Production = 
CALCULATE (
    [Total Sales],
    USERELATIONSHIP ( Sales[Date], ProductionDates[Date] )
)

Но тогда в одном визуале нельзя будет использовать оба календаря одновременно - только по отдельности. Это ограничение.

Интерференция также ломает временные интеллект-функции. SAMEPERIODLASTYEAR, DATEADD работают только с одной таблицей дат, отмеченной как date table. Если вам нужны аналогичные функции для другого календаря, пишите свои меры.

Например, продажи за предыдущий производственный период:

Sales Prev Production Period = 
VAR CurrentPeriod = SELECTEDVALUE ( ProductionPeriods[PeriodKey] )
VAR PrevPeriod = LOOKUPVALUE ( 
    ProductionPeriods[PeriodKey],
    ProductionPeriods[PeriodKey], CurrentPeriod - 1
)
RETURN
    CALCULATE (
        [Total Sales],
        ProductionPeriods[PeriodKey] = PrevPeriod
    )

Это работает, если периоды идут по порядку. Если нет - нужна более сложная логика.

5 ошибок, которые вы совершите (и как их исправить)

Ошибка Почему происходит Как исправить
Пустые значения в неделях Даты, которые не попадают ни в одну неделю по вашему определению (например, 29 февраля в календаре 4-4-5) Убедитесь, что каждая дата имеет назначенный период. Добавьте в таблицу дат столбец с периодом по умолчанию.
Неправильные итоги Меры DAX считают в контексте стандартного календаря, даже когда вы фильтруете по производственному Используйте KEEPFILTERS или перепишите меры с явным указанием таблицы дат через USERELATIONSHIP.
Медленная работа отчетов Сложные меры с FILTER по таблице дат на лету Вынесите логику в расчетные столбцы в таблице дат или в источник данных. Или используйте агрегации.
Конфликт имен столбцов В двух календарях есть столбец "Week", но с разными значениями Используйте префиксы: "ISO Week", "Prod Week". Или поместите каждый календарь в отдельную таблицу.
Сломанная сортировка Текстовые поля типа "Week 1" сортируются как текст: Week 1, Week 10, Week 2 Создайте числовой столбец сортировки и установите его в свойствах столбца.

FAQ: частые вопросы о календарях в Power BI

Можно ли использовать автоматические временные интеллект-функции с пользовательским календарем?

Да, но только если вы пометите таблицу дат как date table (правый клик на таблице -> Mark as date table). Однако эти функции будут работать только с полем даты, которое вы указали как уникальное. Они не будут учитывать ваши пользовательские периоды. Для кастомных периодов пишите свои меры.

Как обрабатывать финансовый год, который начинается не с января?

Добавьте столбец Financial Year в таблицу дат. Логика: если месяц даты больше или равен начальному месяцу финансового года, то финансовый год = год даты, иначе год даты - 1. Например, финансовый год начинается в апреле: Financial Year = YEAR([Date]) + IF(MONTH([Date])>=4,0,-1).

Что делать, если в бизнесе используется несколько календарей одновременно?

Создайте одну таблицу дат со столбцами для каждого календаря. Если периоды разных календарей не совпадают (например, производственные недели и финансовые периоды), то создайте отдельные таблицы периодов и свяжите их с фактами через bridge table или меры с FILTER.

Почему мои недельные отчеты показывают неполные данные на границе годов?

Скорее всего, вы используете WEEKNUM без учета года. Неделя 1 2026 года и неделя 1 2025 года - разные. Используйте составной ключ, например, "2026-W01" или отдельные столбцы Year и Week Number. В визуалах группируйте по обоим.

Как автоматизировать создание таблицы дат с пользовательскими периодами?

Лучше всего создать таблицу в источнике данных (SQL, Excel) и обновлять ее скриптом. Если хотите автоматизацию в Power BI, посмотрите мою статью про автоматизацию Power BI с помощью ИИ. Там есть примеры генерации DAX и схем.

Что в итоге?

Пользовательские календари - это боль. Но если сделать правильно, они превращаются в мощный инструмент. Запомните:

  • Одна таблица дат - много атрибутов.
  • Отношения только по дате, для периодов - bridge table или меры.
  • Пишите меры с учетом контекста фильтрации.
  • Тестируйте на граничных случаях: конец года, високосные годы, пропущенные даты.

И последний совет: если ваш бизнес использует экзотический календарь (скажем, лунный), подумайте, действительно ли он нужен в Power BI. Может, проще преобразовать даты в стандартные периоды на этапе ETL? Иногда проще изменить бизнес-процесс, чем заставить Power BI работать с календарем майя. (Шучу. Но лишь отчасти.)

Подписаться на канал