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

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

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

Базовый механизм объединения ячеек

Для объединения произвольного диапазона ячеек в объекте ТабличныйДокумент используется метод Объединить(), вызываемый у конкретной области. Координаты области задаются номерами начальной и конечной строк, а также начальной и конечной колонок.

Посмотрим на базовый синтаксис получения области и выполнения операции:


Область = ТабДок.Область(НомерСтрокиС, НомерКолонкиС, НомерСтрокиПо, НомерКолонкиПо);
Область.Объединить();

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

Пошаговый алгоритм динамического вывода и объединения

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

  1. Вывод фиксированной левой части таблицы. Сначала выводим вертикальные секции и шапку постоянных колонок с помощью метода Вывести().
  2. Фиксация начальной координаты. Перед началом цикла вывода колонок определяем начальный индекс динамической зоны. Текущую ширину уже заполненной части документа можно узнать через свойство ТабДок.ШиринаТаблицы. Начальной колонкой будет ТабДок.ШиринаТаблицы + 1.
  3. Циклический вывод колонок. В цикле по коллекции дат формируем и выводим колонки методом Присоединить().
  4. Определение конечной координаты. После выхода из цикла свойство ТабДок.ШиринаТаблицы будет указывать на крайнюю правую колонку выведенного диапазона.
  5. Получение и объединение диапазона. Обращаемся к строке общего заголовка по полученным координатам колонок и вызываем метод Объединить().
  6. Заполнение текста и оформления. Устанавливаем заголовок объединенной ячейки и настраиваем центрирование.

Пример программной реализации

Рассмотрим практический пример кода, формирующий динамическую шапку с общим заголовком над колонками дат:


// Предположим, фиксированная левая часть таблицы уже сформирована методом Вывести()
НомерСтрокиЗаголовка = 1;
НомерСтрокиДат = 2;

// Фиксируем колонку, с которой начнется вывод дат
КолонкаНачала = ТабДок.ШиринаТаблицы + 1;

ОбластьКолонкаШапки = Макет.ПолучитьОбласть("КолонкаШапки|КолонкаДаты");

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

// Получаем индекс последней выведенной колонки
КолонкаОкончания = ТабДок.ШиринаТаблицы;

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

Важные правила и ограничения платформы

При программной работе с геометрией ячеек необходимо учитывать следующие особенности платформы 1С:

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

Интерактивная группировка колонок

Если под «группировкой» подразумевается не только визуальное слияние ячеек, но и возможность сворачивать/разворачивать колонки кнопками «+/-», используйте методы ТабДок.НачатьГруппуКолонок() и ТабДок.ЗакончитьГруппуКолонок() либо метод Сгруппировать() у области колонок.

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

Альтернативный вариант: компоновка данных (СКД)

Если отчет строится с использованием Системы компоновки данных, от ручного вычисления координат можно полностью отказаться. Достаточно использовать структуру типа Таблица, поместив группировку по датам в колонки. СКД автоматически рассчитат ширину диапазона, объединит верхние уровни заголовков и сформирует корректную печатную форму без написания процедур объединения в коде.

← На главную