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