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