При формировании отчетов в Системе компоновки данных (СКД) на платформе 1С часто возникает задача отображения данных за период с детализацией по подпериодам. Например, требуется вывести информацию по месяцам, а каждый месяц, в свою очередь, должен быть разбит на недели. При этом, идеальным вариантом является, когда заголовок месяца расположен ровно над всеми колонками своих недель, объединяя их.
Однако, стандартное поведение СКД при создании вложенных группировок по колонкам не всегда дает желаемый визуальный результат. Система может вывести месяц и неделю в одной строке, или же повторять название месяца над каждой неделей, что не создает единого, объединенного заголовка. Давайте подробно разберем, как мы можем достичь требуемого представления, используя возможности СКД и, при необходимости, программную постобработку.
Прежде чем переходить к настройке самого отчета, нам необходимо убедиться, что данные, поступающие в СКД, корректно подготовлены для группировки по месяцам и неделям. Для этого в запросе к источнику данных (создать который поможет консоль запросов для управляемых форм (удобно использовать набор инструментов разработчика 1С с консолью запросов)) мы должны получить начальные даты месяца и недели для каждой записи.
Рассмотрим пример запроса (для отладки которого удобно использовать управляемую консоль запросов), который извлекает данные и формирует необходимые поля для группировки:
ВЫБРАТЬ
ТаблицаДанных.Дата AS Дата,
НАЧАЛОПЕРИОДА(ТаблицаДанных.Дата, МЕСЯЦ) КАК Месяц,
НАЧАЛОПЕРИОДА(ТаблицаДанных.Дата, НЕДЕЛЯ) КАК Неделя,
ТаблицаДанных.Сумма КАК Сумма
ИЗ
ВашаТаблица AS ТаблицаДанных
В этом запросе (где может пригодиться bm Консоль запросов) мы выполняем следующие действия:
Дата) и некий числовой показатель (Сумма) из таблицы данных (в отладке поможет Консоль запросов УФ).НАЧАЛОПЕРИОДА для получения начальной даты месяца (Месяц) и начальной даты недели (Неделя) из исходной даты. Эти поля будут служить основой для наших группировок.Также может быть полезно добавить вычисляемые поля в СКД для более удобного отображения дат в заголовках. Например, для поля Месяц мы можем использовать формат "Январь 2022 г.", а для поля Неделя – "01.01 - 07.01". Это можно сделать как в запросе, так и через вычисляемые поля на закладке "Вычисляемые поля" в настройках СКД.
Пример использования вычисляемых полей в СКД (не в запросе):
ПредставлениеМесяца.
Формат(Месяц, "ДФ=MMMM гггг")
ПредставлениеНедели.
Формат(Неделя, "ДФ=dd.MM") + " - " + Формат(КОНЕЦПЕРИОДА(Неделя, НЕДЕЛЯ), "ДФ=dd.MM")
Именно эти "Представления" мы будем использовать для вывода в заголовках колонок, чтобы информация была максимально читаемой для пользователя.
После подготовки данных в запросе мы переходим к настройке структуры отчета на закладке "Настройки" в СКД.
Месяц (или ПредставлениеМесяца, если мы его создали).Неделя (или ПредставлениеНедели).На данном этапе, если мы сформируем отчет, скорее всего, мы получим результат, похожий на "Январь | 02.05.2022 | 09.05.2022 | ...", как было описано в сообщении 13, или "Январь | Январь | Январь | ...", как в сообщении 19, что не соответствует желаемому объединенному заголовку. Чтобы добиться нужного визуального представления, нам потребуется использовать макеты СКД.
Макеты группировок являются ключевым инструментом для тонкой настройки внешнего вида отчета в СКД, когда стандартные возможности формирования структуры не дают желаемого результата. С их помощью мы можем явно указать, как должен выглядеть заголовок для определенной группировки.
Рассмотрим пошагово, как создать макет для нашей группировки "Месяц", чтобы она объединяла заголовок над неделями:
Месяц (или ПредставлениеМесяца).После установки этих параметров нажимаем "Далее".
Месяц (или ПредставлениеМесяца). В ячейке появится текст вроде [Месяц].После этих действий СКД, при формировании отчета, будет использовать созданный нами макет для отображения заголовков месяцев. Месяц будет отображаться как единый заголовок, объединяющий ячейки над соответствующими неделями, создавая желаемую иерархическую структуру.
Важный момент: Макеты являются мощным, но иногда непростым в освоении инструментом. Требуется некоторое экспериментирование с выделением областей, параметрами и форматированием, чтобы добиться идеального результата. Однако, это "родной" способ для СКД, и он обычно является наиболее устойчивым к изменениям в данных.
В некоторых случаях, когда средствами макетов СКД не удается добиться нужного результата (например, из-за очень сложной и динамической структуры отчета, которую СКД генерирует непредсказуемо), мы можем прибегнуть к программной постобработке уже сформированного табличного документа — для этого есть инструмент для программной постобработки табличных документов в 1С.
Этот метод заключается в том, что после того, как СКД сформирует отчет в табличный документ, мы вручную (программно) обходим нужные области этого документа и объединяем ячейки, перемещаем текст или меняем форматирование. Для этого используется событие ПриКомпоновкеРезультата формы отчета.
Рассмотрим общую логику и примерный скелет кода для такой постобработки:
ПриКомпоновкеРезультата. В модуле формы отчета нам необходимо создать (или переопределить) процедуру с таким именем.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, Отчет, ДанныеРасшифровки)
// Здесь будет наш код постобработки
КонецПроцедуры
Параметр ДокументРезультат – это наш сформированный табличный документ, с которым мы будем работать.
ДанныеРасшифровки для получения более детальной информации о структуре вывода, хотя это также может быть нетривиально.Предположим, что СКД, несмотря на группировки, все равно вывела повторяющиеся заголовки месяцев над каждой неделей (как в сообщении 19: "Январь | Январь | Январь" над неделями). Наша задача — найти эти повторяющиеся ячейки и объединить их в одну.
// Примерный скелет кода в процедуре ПриКомпоновкеРезультата()
// Этот код сильно упрощен и требует адаптации под конкретный отчет
Перем НомерСтрокиЗаголовковМесяцев;
// Здесь нужно определить реальный номер строки, где СКД вывела заголовки месяцев.
// Это может быть 3, 4 или другая строка, в зависимости от других группировок.
// Допустим, мы знаем, что месяцы находятся в 3-й строке табличного документа.
НомерСтрокиЗаголовковМесяцев = 3;
Если ДокументРезультат.Области.Количество() > 0 Тогда
// Проходим по всей ширине табличного документа в строке с месяцами
Перем ТекущаяКолонка = 1;
Пока ТекущаяКолонка <= ДокументРезультат.ШиринаТаблицы Цикл
Перем ТекстМесяца = ДокументРезультат.Область(НомерСтрокиЗаголовковМесяцев, ТекущаяКолонка).Текст;
Если Не ПустаяСтрока(ТекстМесяца) Тогда // Если это не пустая ячейка
Перем КолонкаКонцаМесяца = ТекущаяКолонка;
// Ищем все соседние ячейки в той же строке, которые содержат тот же текст месяца
Пока КолонкаКонцаМесяца + 1 <= ДокументРезультат.ШиринаТаблицы
И ДокументРезультат.Область(НомерСтрокиЗаголовковМесяцев, КолонкаКонцаМесяца + 1).Текст = ТекстМесяца
Цикл
КолонкаКонцаМесяца = КолонкаКонцаМесяца + 1;
КонецЦикла;
// Если мы нашли более одной ячейки с одинаковым текстом, объединяем их
Если КолонкаКонцаМесяца > ТекущаяКолонка Тогда
ДокументРезультат.ОбъединитьЯчейки(НомерСтрокиЗаголовковМесяцев, ТекущаяКолонка, НомерСтрокиЗаголовковМесяцев, КолонкаКонцаМесяца);
КонецЕсли;
// Для корректного отображения, возможно, потребуется установить выравнивание по центру
ДокументРезультат.Область(НомерСтрокиЗаголовковМесяцев, ТекущаяКолонка).ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
КонецЕсли;
// Переходим к следующей необъединенной ячейке
ТекущаяКолонка = КолонкаКонцаМесяца + 1;
КонецЦикла;
КонецЕсли;
Важное замечание: Программная постобработка является очень мощным, но при этом наиболее "хрупким" решением. Она сильно зависит от точной структуры табличного документа, который формирует СКД. Любое незначительное изменение в настройках отчета, группировках или даже в версии платформы может привести к изменению структуры табличного документа, и ваш код постобработки перестанет работать корректно. Поэтому, этот метод рекомендуется использовать только в крайних случаях, когда макеты СКД не дают желаемого результата.
Месяц и Неделя (или их вычисляемых аналогов) установлена соответствующая сортировка (по возрастанию).Задача разбиения периода на подпериоды в колонках отчета СКД с иерархическим представлением заголовков (месяц над неделями) является одной из более сложных задач форматирования в СКД. Мы выяснили, что наиболее предпочтительным и устойчивым способом решения является использование макетов группировок. Они позволяют нам явно определить, как должен выглядеть заголовок родительской группировки, чтобы он объединял ячейки над своими дочерними элементами.
В случаях, когда макеты оказываются недостаточными или слишком сложными для реализации специфических требований, мы можем применить программную постобработку табличного документа. Однако, следует помнить о потенциальной хрупкости такого решения при изменениях в структуре отчета. Начинать всегда следует с максимально доступных и "родных" средств СКД, а именно с макетов.