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