Как вывести сложную двухуровневую шапку с динамическими колонками и объединить ячейки в табличном документе 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При формировании нестандартных отчетов и кросс-таблиц разработчики часто сталкиваются с задачей вывода сложной двухуровневой шапки. Типичная структура выглядит следующим образом: первая колонка (например, «Валюта» или «Номенклатура») объединяет две строки по вертикали, а следующие за ней колонки динамически добавляются по горизонтали, причем над ними должна быть расположена общая объединенная ячейка верхнего уровня (например, «Периоды»), а под ней — конкретные значения колонок.

Попытки решить эту задачу «в лоб» через получение произвольных пересечений областей или объединение ячеек в макете до вывода приводят к программным ошибкам или искажению сетки таблицы. Разберем по шагам причины возникающих проблем и рассмотрим рабочие способы реализации такой структуры.

Почему возникают ошибки при выводе сложных областей

Проанализируем две ключевые ошибки, с которыми сталкиваются при конструировании сложных макетов:

  1. Ошибочное обращение к пересечению областей. Конструкция Макет.ПолучитьОбласть("Область1|Область2") работает строго по принципу «Строка|Колонка», то есть одна область в макете обязана быть горизонтальной (строка), а вторая — вертикальной (колонка). Если обе именованные области заданы как горизонтальные или имеют несогласованные границы, платформа 1С вызывает исключение «Область не найдена».
  2. Попытка вызова метода Объединить() у промежуточной области макета. Объект, возвращаемый методом Макет.ПолучитьОбласть(), представляет собой временный фрагмент таблицы в оперативной памяти. Изменение границ и объединение ячеек внутри него до вывода либо игнорируются при вставке в итоговый документ через Вывести() и Присоединить(), либо приводят к искажению разметки. Все операции объединения необходимо производить непосредственно в результирующем объекте ТабличныйДокумент после того, как строки и колонки уже физически выведены на экран или сформированы в памяти.

Способ 1. Поколоночный вывод с последующим программным объединением

Рассмотрим основной и самый универсальный алгоритм. Метод Присоединить() всегда прикрепляет новую колонку, ориентируясь на верхнюю границу текущей выведенной строки. Поэтому шаблон макета настраивается так, чтобы и фиксированная левая колонка, и присоединяемые динамические колонки имели одинаковую базовую высоту — ровно в 2 строки.

Разберем процесс поэтапно:

  1. В макете создаем горизонтальную секцию высотой в две строки (например, ШапкаТаблицы) и вертикальные секции: фиксированную КолонкаВалюта и динамическую КолонкаПериод.
  2. Левая ячейка валюты может быть объединена заранее в самом макете по двум строкам. Динамическая колонка периода в макете содержит две раздельные строки: верхняя предназначена под общий заголовок, нижняя — под наименование конкретного периода.
  3. Выводим сначала фиксированную левую область методом Вывести(), затем в цикле добавляем колонки периодов методом Присоединить().
  4. После завершения цикла обращаемся к сформированному диапазону в верхней строке результирующего табличного документа и объединяем ячейки, устанавливая нужный текст и параметры выравнивания.

Посмотрим на программный код реализации этого подхода:


// Получаем области пересечения: строка макета высотой в 2 ячейки и соответствующие колонки
ОбластьШапкаВалюта = Макет.ПолучитьОбласть("ШапкаТаблицы|КолонкаВалюта");
ОбластьШапкаПериод = Макет.ПолучитьОбласть("ШапкаТаблицы|КолонкаПериод");

// Выводим первую фиксированную колонку (в макете она уже объединена по высоте в 2 строки)
ТабДок.Вывести(ОбластьШапкаВалюта);

// Запоминаем номер строки шапки и начальную позицию динамических колонок
НомерСтрокиШапки = ТабДок.ВысотаТаблицы - 1; // верхняя строка шапки
НачальнаяКолонка = ТабДок.ШиринаТаблицы + 1;

// В цикле присоединяем динамические колонки периодов
Для Каждого СтрПериод Из ТзПериоды Цикл
    ОбластьШапкаПериод.Параметры.ПериодНаименование = СтрПериод.Представление;
    ТабДок.Присоединить(ОбластьШапкаПериод);
КонецЦикла;

КонечнаяКолонка = ТабДок.ШиринаТаблицы;

// Объединяем верхнюю строку над выведенными динамическими колонками
Если КонечнаяКолонка >= НачальнаяКолонка Тогда
    ОбластьЗаголовка = ТабДок.Область(НомерСтрокиШапки, НачальнаяКолонка, НомерСтрокиШапки, КонечнаяКолонка);
    ОбластьЗаголовка.Объединить();
    ОбластьЗаголовка.Текст = "Периоды отчета";
    ОбластьЗаголовка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Центр;
    ОбластьЗаголовка.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;

В этом примере свойства ТабличныйДокумент.ВысотаТаблицы и ТабличныйДокумент.ШиринаТаблицы позволяют динамически определить точные координаты области без жесткой привязки к фиксированным номерам строк, что делает алгоритм универсальным.

Способ 2. Центрирование по выделенным колонкам без физического объединения

Если требуется избежать изменения структуры ячеек и физического вызова метода Объединить(), можно воспользоваться специальным свойством выравнивания текста платформы 1С.

Разберем логику работы этого метода:

  1. В макете для верхней ячейки секции динамической колонки устанавливаем свойство ГоризонтальноеПоложение = ГоризонтальноеПоложение.ВыделенныеКолонки.
  2. При выводе колонок в цикле текст заголовка группы помещаем исключительно в самую первую колонку динамического диапазона.
  3. Во всех последующих динамических колонках верхняя ячейка оставляется пустой.

Платформа автоматически отцентрирует текст первой ячейки по всей ширине смежных пустых ячеек с таким же свойством, визуально создавая эффект объединенного заголовка без дробления координатной сетки.

Управление шириной колонок и переносом текста

Часто при выводе динамических заголовков текст не помещается в стандартную ячейку. Для решения этой проблемы используются два механизма:

  1. Программное изменение ширины колонки. Чтобы задать размер колонки в символах, обращаемся к свойству ШиринаКолонки области всей вертикальной колонки табличного документа:
    
    // Установка ширины конкретной колонки документа
    ТабДок.Область(, НомерКолонки, , НомерКолонки).ШиринаКолонки = 18;
    
  2. Автоматический перенос текста и расчет высоты. Для ячейки устанавливается свойство РазмещениеТекста в значение ТипРазмещенияТекстаТабличногоДокумента.Переносить. При этом строка в макете не должна иметь жестко зафиксированной высоты в пунктах — тогда свойство АвтоВысотаСтроки автоматически увеличит размер строки под объем выводимого содержимого.

Использование Системы компоновки данных (СКД)

В современной разработке на платформе 1С для отчетов со сложными кросс-таблицами рекомендуется переходить на СКД. В схеме компоновки создается структура типа «Таблица», где группировка строк содержит постоянные разрезы (например, валюту), а группировка колонок — периодичность. СКД автоматически рассчитывает вложенные заголовки, объединяет шапки и управляет шириной колонок без необходимости ручного вычисления координат ячеек в коде.

← На главную