При разработке аналитических отчетов в системе компоновки данных (СКД) часто возникает задача вывести данные в виде кросс-таблицы, где в строках располагается номенклатура или контрагенты, а в колонках — иерархия периодов. Например, пользователь хочет видеть общие итоги за год, иметь возможность развернуть год до месяцев, а месяцы — до недель. Реализация такой задачи требует правильной подготовки запроса и специфических настроек самой компоновки. Рассмотрим подробно, как это сделать.
Для того чтобы СКД могла строить иерархию, нам необходимо предоставить ей все уровни периодов в явном виде. Просто выбрать дату транзакции недостаточно. Мы должны создать отдельные поля для года, месяца и недели, используя функцию НАЧАЛОПЕРИОДА. Это позволит системе группировать данные по этим точкам отсчета.
Проанализируем пример запроса к виртуальной таблице оборотов регистра накопления. Важно учитывать, что если мы используем виртуальную таблицу Обороты, то периодичность в параметрах таблицы лучше ставить Авто или Регистратор, чтобы иметь доступ к детальным данным для расчета всех уровней периодов.
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК Количество,
ПродажиОбороты.СуммаОборот КАК Сумма,
НАЧАЛОПЕРИОДА(ПродажиОбороты.Период, ГОД) КАК ПериодГод,
НАЧАЛОПЕРИОДА(ПродажиОбороты.Период, МЕСЯЦ) КАК ПериодМесяц,
НАЧАЛОПЕРИОДА(ПродажиОбороты.Период, НЕДЕЛЯ) КАК ПериодНеделя
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты
В данном запросе мы подготовили три поля, которые станут основой для наших колонок. Обратите внимание, что использование ВЫБОР КОГДА ... ЕСТЬ NULL (как обсуждалось в сообщениях форума) актуально при использовании левых соединений, но для прямой выборки из оборотов достаточно стандартных функций.
После написания запроса перейдем на закладку "Наборы данных" в конструкторе СКД. Это критически важный этап, о котором часто забывают. Чтобы СКД понимала, что ПериодГод, ПериодМесяц и ПериодНеделя связаны между собой хронологически, необходимо настроить их Роли.
ПериодГод в колонке "Роль" укажите, что это период, и установите порядковый номер (например, 1).ПериодМесяц укажите роль "Период" с порядковым номером 2.ПериодНеделя — роль "Период" с номером 3.Такая настройка поможет системе правильно вычислять итоги и обеспечит корректную работу стандартных механизмов дополнения периодов.
Теперь настроим визуальное представление. Перейдите на закладку "Настройки". Вместо привычного "Детальные записи" или "Группировка", нам нужно создать структуру типа "Таблица".
Разберем внутреннюю иерархию таблицы:
Номенклатура (или другой аналитике).ПериодГод.ПериодМесяц.ПериодНеделя.При такой настройке в результирующем отчете появятся плюсики, позволяющие сворачивать и разворачивать периоды прямо в колонках.
В процессе обсуждения на форуме была поднята важная проблема: неделя может начинаться в одном месяце, а заканчиваться в другом. Если мы просто вложим ПериодНеделя в ПериодМесяц, СКД может визуально "разорвать" неделю на две колонки (одна часть данных попадет в конец одного месяца, другая — в начало следующего). Это происходит потому, что поле ПериодНеделя содержит дату понедельника, которая может быть меньше даты начала текущего месяца.
Чтобы избежать путаницы и сделать отчет более читаемым (как в примере из сообщения 12), проанализируем вариант использования Вычисляемых полей. Мы можем создать поле ОтображаемаяНеделя, которое будет "прижиматься" к границе месяца.
В поле "Выражение" для вычисляемого поля можно написать:
ВЫБОР КОГДА НАЧАЛОПЕРИОДА(Период, МЕСЯЦ) > НАЧАЛОПЕРИОДА(Период, НЕДЕЛЯ) ТОГДА НАЧАЛОПЕРИОДА(Период, МЕСЯЦ) ИНАЧЕ НАЧАЛОПЕРИОДА(Период, НЕДЕЛЯ) КОНЕЦ
Однако более профессиональным подходом является использование настройки "Дополнение периодов". В настройках группировки колонок выберите поле периода, перейдите на вкладку "Иерархия группировки" и установите тип дополнения (День, Неделя или Месяц). Это заставит отчет выводить колонки даже для тех периодов, в которых не было продаж, сохраняя целостность временной шкалы.
Чтобы в шапке отчета вместо дат (например, "01.01.2023 00:00:00") выводились красивые названия, воспользуемся колонкой "Выражение представления" на вкладке "Наборы данных".
Рассмотрим примеры форматирования:
ПериодМесяц: Формат(ПериодМесяц, "ДФ='ММММ гггг'") — выведет "Январь 2023".ПериодНеделя можно использовать выражение: "Неделя с " + Формат(ПериодНеделя, "ДЛФ=D").Также стоит заглянуть в "Условное оформление". Там можно настроить минимальную ширину колонок, чтобы при развороте до недель отчет не растягивался слишком сильно, и зафиксировать заголовки, чтобы при скроллинге пользователь всегда видел, к какому периоду относятся данные.
Если вам нужно, чтобы пользователь сам выбирал, в каком разрезе смотреть отчет (только месяцы или только недели), можно применить подход из сообщения 15. Вместо жесткой иерархии в запросе, создается параметр &Периодичность.
В самом запросе или в вычисляемом поле прописывается логика:
ВЫБОР
КОГДА &Периодичность = "Неделя" ТОГДА НАЧАЛОПЕРИОДА(Период, НЕДЕЛЯ)
КОГДА &Периодичность = "Месяц" ТОГДА НАЧАЛОПЕРИОДА(Период, МЕСЯЦ)
ИНАЧЕ НАЧАЛОПЕРИОДА(Период, ДЕНЬ)
КОНЕЦ
Это поле выводится в колонки таблицы. Таким образом, структура отчета остается неизменной, а детальность данных меняется в зависимости от выбора пользователя в настройках.
Резюмируем: Для создания качественного отчета с группировкой периодов в колонках необходимо подготовить данные через НАЧАЛОПЕРИОДА, правильно настроить роли полей в СКД и использовать структуру типа "Таблица". Использование вычисляемых полей и выражений представления позволит сделать отчет не только функциональным, но и удобным для конечного бизнес-пользователя.