В процессе разработки отчетов на Системе компоновки данных (СКД) часто возникает задача динамического формирования заголовков колонок или строковых представлений для периодов. Например, вместо стандартной даты пользователю удобнее видеть текст вида «С 01.05.2022 по 31.05.2022» или «I квартал 2023 г.». Попытки решить эту задачу напрямую в тексте запроса с помощью функций работы со строками (например, ПОДСТРОКА) часто приводят к громоздкому коду и ошибкам производительности.
В этой статье мы разберем наиболее эффективные способы решения этой задачи, используя встроенные механизмы СКД, такие как выражения представления, макеты оформления и вычисляемые поля.
Разберем самый правильный с точки зрения архитектуры СКД метод. Вместо того чтобы преобразовывать дату в строку в запросе, мы оставим в поле тип Дата, но укажем системе, как именно ее нужно отображать пользователю. Это позволит сохранить правильную сортировку (по дате, а не по алфавиту) и при этом вывести нужный текст.
Для этого в конструкторе схемы компоновки данных перейдем на вкладку Наборы данных. Найдем наше поле периода и в колонке Выражение представления пропишем логику в зависимости от выбранной периодичности. Рассмотрим пример, когда периодичность передается в отчет через параметр &Периодичность:
ВЫБОР
КОГДА &Периодичность = 1
ТОГДА Формат(Период, "ДФ='ММММ гггг ""г.""' ") // Например: Май 2022 г.
КОГДА &Периодичность = 2
ТОГДА Формат(Период, "ДФ='к ""квартал"" гггг ""г.""'" ) // Например: 2 квартал 2022 г.
КОГДА &Периодичность = 3
ТОГДА Формат(Период, "ДФ='гггг ""г.""'") // Например: 2022 г.
ИНАЧЕ Формат(Период, "ДФ='дд.ММ.гггг'")
КОНЕЦ
Проанализируем эту ситуацию: функция Формат внутри СКД работает аналогично одноименной функции встроенного языка. Используя различные маски ДФ, мы можем добиться практически любого стандартного представления даты.
Стандартная маска формата не всегда позволяет вывести специфические интервалы, такие как декада или полугодие. В этом случае в Выражении представления или в Вычисляемом поле нам придется использовать математические операции над датой. Для быстрой настройки вывода подобных интервалов можно использовать готовый пример формирования шапки отчета по неделям и месяцам в СКД.
Рассмотрим, как реализовать сложные представления:
НачалоПериода и КонецПериода:
"Неделя с " + Формат(НачалоПериода(Период, "Неделя"), "ДФ=dd.MM.yyyy") + " по " + Формат(КонецПериода(Период, "Неделя"), "ДФ=dd.MM.yyyy")
ВЫБОР
КОГДА День(Период) <= 10 ТОГДА "1 декада "
КОГДА День(Период) <= 20 ТОГДА "2 декада "
ИНАЧЕ "3 декада "
КОНЕЦ + Формат(Период, "ДФ='MMMM yyyy'")
ВЫБОР
КОГДА Месяц(Период) <= 6 ТОГДА "I полугодие "
ИНАЧЕ "II полугодие "
КОНЕЦ + Формат(Период, "ДФ=yyyy")
Если нам нужно изменить не значение внутри колонки, а именно заголовок группировки (например, в кросс-таблице), лучше всего воспользоваться вкладкой Макеты. Это позволит создать шаблон оформления ячейки, который будет выглядеть максимально эстетично.
Разберем по шагам процесс создания такого макета:
Период).С [ДатаНачала] по [ДатаОкончания].ДатаНачала и ДатаОкончания с выражениями. Например: НачалоПериода(Период, "Месяц") и КонецПериода(Период, "Месяц") соответственно.Этот метод позволяет полностью контролировать визуальное представление, включая шрифты, цвета и рамки, что невозможно сделать простым выражением в наборе данных.
Выясним причину, по которой иногда стоит выносить логику представления в программный код. Если алгоритм формирования заголовка очень сложный (например, нужно учитывать склонения месяцев или специфические праздничные интервалы), писать это в СКД неудобно. В таком случае мы можем вызвать функцию общего модуля прямо из выражения СКД.
Важное условие: общий модуль должен иметь флаги Сервер, Внешнее соединение и Клиент. Сама функция должна быть экспортной.
Пример вызова в поле Выражение представления:
МойОбщийМодуль.СформироватьЗаголовокПериода(Период, &Периодичность)
В самом модуле код может выглядеть так:
Функция СформироватьЗаголовокПериода(ДатаПериода, ТипПериодичности) Экспорт
Если ТипПериодичности = Перечисления.Периодичность.Месяц Тогда
Возврат Формат(ДатаПериода, "ДФ='ММММ гггг'");
КонецЕсли;
// ... остальная логика
КонецФункции
Проанализируем ситуацию, когда сортировка в отчете ломается после применения представлений. Чтобы этого не произошло, убедитесь, что на вкладке Наборы данных в колонке Роль для полей периодов указано, что они являются периодами. Для этого нажмите на «лупу» в колонке роль, установите флаг Период и укажите порядковый номер (например, 1 для года, 2 для месяца и т.д.). Это критически важно для корректной работы иерархии и автоматических итогов в СКД.
Резюме: для простых задач используйте Формат() в выражении представления. Для сложных заголовков в кросс-таблицах — Макеты. А если нужно обеспечить единообразие во всех отчетах конфигурации — выносите логику в Общие модули.