При разработке отчетов на базе Системы компоновки данных (СКД) разработчики часто сталкиваются с необходимостью визуально объединить несколько колонок в группы. Если нам нужно создать одну группу, проблем обычно не возникает. Однако, как только на одном уровне появляется две и более групп выбранных полей с вертикальным расположением, мы сталкиваемся со специфическим поведением платформы 1С:Предприятие.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы СКД и рассмотрим несколько практических способов обхода этой особенности — как с использованием макетов, так и полностью терапевтическими методами без жесткого кодирования структуры.
Давайте проанализируем ситуацию. Когда мы настраиваем выбранные поля в СКД и объединяем их в логические группы (например, создаем две группы полей, расположенные рядом друг с другом), система компоновки пытается оптимизировать шапку итоговой таблицы. При этом возможны два нежелательных сценария:
Выяснив причину такого поведения, давайте разберем по шагам доступные способы решения этой задачи.
---
Очень часто разработчики настраивают структуру выбранных полей на самом верхнем уровне настроек отчета — на уровне «Отчет». При этом СКД применяет наиболее жесткие правила оптимизации шапки. Мы можем перехитрить систему, если перенесем настройки полей непосредственно в параметры конкретной группировки.
Рассмотрим этот процесс по шагам:
При локальной настройке на уровне конкретной ветки структуры СКД во многих релизах платформы ведет себя менее агрессивно. Она корректно выведет вертикальные группы полей рядом друг с другом без создания лишних пустых строк в шапке.
---
Если нам необходимо гарантировать стопроцентный результат при любых настройках отчета и при этом сохранить для пользователя возможность интерактивно менять структуру (менять группировки местами, добавлять новые поля), лучшим решением будет программная обработка готового табличного документа.
Суть метода заключается в том, что мы намеренно задаем группам уникальные технические заголовки (например, ##Скрыть1## и ##Скрыть2##). Благодаря уникальности имен СКД не объединит наши колонки. А после вывода отчета мы найдем эти маркеры в табличном документе и аккуратно их «зачистим».
Разберем по шагам реализацию этого механизма в модуле объекта отчета:
##Скрыть1##, а для второй — ##Скрыть2##.ПриКомпоновкеРезультата.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Отключаем стандартный вывод, так как мы будем выводить отчет программно
СтандартнаяОбработка = Ложь;
// Инициализируем компоненты вывода СКД
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
// Начинаем вывод отчета
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
// Анализируем полученный табличный документ и удаляем технические заголовки
КоличествоСтрок = ДокументРезультат.ВысотаТаблицы;
КоличествоКолонок = ДокументРезультат.ШиринаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
Для НомерКолонки = 1 По КоличествоКолонок Цикл
ТекущаяОбласть = ДокументРезультат.Область(НомерСтроки, НомерКолонки);
ТекстЯчейки = СокрЛП(ТекущаяОбласть.Текст);
// Если находим наш маркер скрытия
Если Найти(ТекстЯчейки, "##Скрыть") > 0 Тогда
// Очищаем текст ячейки
ТекущаяОбласть.Текст = "";
// Убираем верхнюю и нижнюю границы ячейки, чтобы слить ее с соседними
ТекущаяОбласть.ГраницаСверху = Новый Линия(ТипЛинииСтенкиЯчейки.Нет);
ТекущаяОбласть.ГраницаСнизу = Новый Линия(ТипЛинииСтенкиЯчейки.Нет);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Этот способ крайне надежен. Пользователь может настраивать группировки строк, менять их местами, добавлять свои отборы — программный код отработает по факту генерации финального документа и аккуратно уберет визуальные артефакты.
---
Если мы не хотим писать программный код в модуле объекта и стремимся решить задачу исключительно стандартными интерактивными настройками, мы можем прибегнуть к условной маскировке границ ячеек.
Проанализируем ситуацию: пустая строка шапки физически создается платформой, и мы не можем заставить СКД удалить ее стандартными настройками. Но мы можем сделать ее абсолютно невидимой для человеческого глаза!
Для этого выполним следующие действия:
Нет.Нет.В результате пустая ячейка физически останется в табличном документе, но у нее исчезнут визуальные границы и текст. Она визуально сольется с основной шапкой отчета, и пользователь не заметит лишних пустых строк.
---
Когда разработчики слышат фразу «использование макетов в СКД», они часто пугаются, ведь создание собственного макета для всего отчета полностью лишает пользователя возможности гибко настраивать структуру (группировки, колонки и т.д.). Однако в СКД можно переопределить макет только для одной конкретной группировки, оставив вывод остальной части отчета полностью автоматическим.
Рассмотрим этот изящный прием подробнее:
ИмяМоейГруппировки.ИмяМоейГруппировки.Что произойдет при выводе отчета? СКД, дойдя до вывода шапки для группировки ИмяМоейГруппировки, обратится к макету и увидит, что он пустой. Система просто проигнорирует вывод этой части шапки, при этом само тело таблицы с детальными записями и показателями выведется стандартным автоматическим образом. Мы получим красивую таблицу без лишних строк в шапке, сохранив при этом работоспособность пользовательских настроек.
---
Мы подробно разобрали четыре различных подхода к решению проблемы группировки полей на одном уровне в СКД. Какой из них выбрать?