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

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

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

Анализ проблемы: почему не работает обычное присоединение

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

Способ 1: Метод постобработки (слияние после вывода)

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

Разберем по шагам, как реализовать этот алгоритм в коде:

  1. Запоминаем начальную позицию (номер текущей строки в ТабличныйДокумент).
  2. Выводим данные в цикле.
  3. Определяем конечную позицию.
  4. Обращаемся к нужной области колонок и вызываем метод Объединить().

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


// Запоминаем номер строки, с которой начинается объединение
НомерНачала = ТабДок.ВысотаТаблицы + 1;

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

// Формируем и присоединяем правую часть
ПрикрепляемыйТабДок = Новый ТабличныйДокумент;
Пока Выборка.Следующий() Цикл
    СтрокаДанных = Макет.ПолучитьОбласть("Строка");
    // Заполнение параметров...
    ПрикрепляемыйТабДок.Вывести(СтрокаДанных);
КонецЦикла;

ТабДок.Присоединить(ПрикрепляемыйТабДок);

// Теперь выполняем объединение левой колонки по всей высоте
НомерКонца = ТабДок.ВысотаТаблицы;
Если НомерКонца > НомерНачала Тогда
    // Обратите внимание: индексы колонок должны соответствовать вашему макету
    ОбластьДляОбъединения = ТабДок.Область(НомерНачала, 1, НомерКонца, 1);
    ОбластьДляОбъединения.Объединить = Истина;
    ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;

Важные нюансы при работе с методом Объединить

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

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

Область.Объединить = Ложь;

После этого можно смело устанавливать Область.Объединить = Истина;. Это очистит структуру ячеек и создаст новое чистое объединение по заданным координатам.

Способ 2: Визуальная имитация (без реального объединения)

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

Разберем, как это работает:

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

Этот метод позволяет добиться визуального эффекта "единого блока" без фактического использования ресурсоемкой операции Объединить(). Также это значительно упрощает последующую выгрузку документа в Excel, так как объединенные ячейки часто мешают пользователям использовать фильтры и сортировки.

Работа с оформлением и границами

Когда мы программно объединяем области, часто "слетают" настройки границ (Borders), заданные в макете. Проанализируем, как этого избежать. Рекомендуется устанавливать границы программно сразу после вызова метода Объединить(). Это гарантирует, что рамка будет обводить всю новую область целиком, а не отдельные ячейки внутри нее.

Пример программной установки границ:


Область = ТабДок.Область(НачалоСтр, НачалоКол, КонецСтр, КонецКол);
Область.Объединить = Истина;
// Устанавливаем тонкие сплошные линии по периметру
Область.ГраницаСверху = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
Область.ГраницаСнизу = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
Область.ГраницаСлева = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);
Область.ГраницаСправа = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная, 1);

Способ 3: Использование временного табличного документа

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

Сначала мы полностью формируем правую (динамическую) часть во временном документе. Затем проверяем свойство ВременныйТабДок.ВысотаТаблицы. Получив это число, мы можем подготовить в основном документе область нужной высоты (сразу объединив строки) и только после этого использовать Присоединить(). Это избавляет от необходимости "подтирать" границы или пересчитывать координаты постфактум.

Посмотрим на пример логики:


ВременныйТабДок = Новый ТабличныйДокумент;
// Заполняем временный документ строками из выборки...
// ...
ВысотаРезультата = ВременныйТабДок.ВысотаТаблицы;

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

// Объединяем выведенные строки шапки
ТабДок.Область(ТекущаяСтрока, 1, ТекущаяСтрока + ВысотаРезультата - 1, 1).Объединить = Истина;

// Присоединяем данные
ТабДок.Область(ТекущаяСтрока, 2).Присоединить(ВременныйТабДок);

Используя предложенные методы, вы сможете гибко управлять структурой табличного документа, создавая сложные и профессионально оформленные печатные формы в 1С. Выбор конкретного метода зависит от требований к производительности и сложности структуры вашего макета.

← На главную