Как программно объединить ячейки по вертикали в табличном документе 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При формировании печатных форм в системе «1С:Предприятие 7.7» разработчики часто сталкиваются с задачей визуальной оптимизации таблиц. Одной из наиболее распространенных задач является объединение смежных строк с одинаковыми значениями в одной колонке. Например, при выводе реестра документов по разным контрагентам или списка заказов с одинаковыми адресами доставки логично сгруппировать дублирующиеся записи по вертикали. Это делает документ читаемым и аккуратным.

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

Теоретическая база: Метод Объединить() и работа с областями

Для программного управления ячейками в платформе 1С 7.7 используется встроенный объект Таблица. Чтобы объединить группу ячеек, нам сначала необходимо получить доступ к конкретному диапазону (области) этой таблицы, а затем вызвать соответствующий метод.

Синтаксис получения области выглядит следующим образом:

Таб.Область(Верх, Лево, Низ, Право)

Где параметры принимают числовые значения границ области:

Если нам необходимо объединить ячейки только в одной конкретной колонке по вертикали, параметры Лево и Право будут одинаковыми (будут указывать на номер этой колонки). Непосредственно для слияния ячеек применяется метод Объединить().

Рассмотрим базовый пример: если нам нужно объединить ячейки в первой колонке со строки №5 по строку №10, команда будет выглядеть так:

Таб.Область(5, 1, 10, 1).Объединить();

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

Алгоритм динамического расчета координат областей

В реальных отчетах количество выводимых строк заранее неизвестно, так как данные берутся динамически из справочников, документов или таблиц значений. Соответственно, мы не можем «зашить» жесткие номера строк в код. Нам необходимо рассчитывать координаты Верх и Низ прямо во время вывода секций.

Давайте детально разберем алгоритм решения этой задачи:

  1. Перед началом вывода строк таблицы мы инициализируем переменную НачалоОбъединения. Ее начальное значение должно быть равно номеру первой строки, которая будет выведена в табличную часть (ее можно определить как Таб.ВысотаТаблицы() + 1 после вывода шапки).
  2. Также создаем переменную для хранения текущего группировочного значения (например, ТекущийАдрес = "").
  3. Запускаем цикл обхода данных (например, строк таблицы значений или выборки запроса).
  4. Внутри цикла, перед выводом очередной секции, мы выполняем проверку: изменилось ли ключевое значение по сравнению с предыдущей итерацией?
  5. Если значение изменилось (и это не самая первая итерация), мы фиксируем границу предыдущей группы. Конечной строкой группы будет текущая высота таблицы: КонецОбъединения = Таб.ВысотаТаблицы().
  6. Если КонецОбъединения строго больше, чем НачалоОбъединения, это означает, что в группе накопилось две или более строк. В этом случае мы вызываем метод Объединить() для накопленной области.
  7. После объединения мы сдвигаем НачалоОбъединения на следующую строку (которая сейчас будет выводиться): Таб.ВысотаТаблицы() + 1, и обновляем значение переменной ТекущийАдрес.
  8. Выводим текущую секцию строки.
  9. Критически важный шаг: После полного завершения цикла необходимо обязательно выполнить постобработку. Последняя группа строк не будет объединена внутри цикла, так как условие смены значения больше не сработает. Поэтому мы принудительно делаем финальную проверку и объединяем последнюю область от НачалоОбъединения до текущей высоты таблицы.

Практический пример реализации в коде

Давайте посмотрим на практический пример кода, написанный на встроенном языке 1С 7.7. Предположим, у нас есть заполненная таблица значений ТЗ с колонками АдресДоставки и Контрагент. Наша задача — вывести эти данные в макет и объединить строки по одинаковым адресам в первой колонке.


Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Макет");
Таб.ВывестиСекцию("Шапка"); // Вывели шапку отчета

// Определяем номер целевой колонки для объединения (например, первая колонка)
НомерКолонкиАдреса = 1; 

// Инициализируем начальные координаты
НачалоОбъединения = Таб.ВысотаТаблицы() + 1;
ТекущийАдрес = "";

ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    
    // Проверяем, изменился ли адрес по сравнению с предыдущей строкой
    Если (ТЗ.АдресДоставки <> ТекущийАдрес) И (ТекущийАдрес <> "") Тогда
        
        КонецОбъединения = Таб.ВысотаТаблицы();
        
        // Объединяем область, если в ней накопилось больше одной строки
        Если КонецОбъединения > НачалоОбъединения Тогда
            Таб.Область(НачалоОбъединения, НомерКолонкиАдреса, КонецОбъединения, НомерКолонкиАдреса).Объединить();
        КонецЕсли;
        
        // Устанавливаем точку отсчета для следующей уникальной группы
        НачалоОбъединения = Таб.ВысотаТаблицы() + 1;
        
    КонецЕсли;
    
    // Запоминаем текущее значение для последующих сравнений
    ТекущийАдрес = ТЗ.АдресДоставки;
    
    // Заполняем параметры секции "Строка"
    АдресПечать = ТЗ.АдресДоставки;
    КонтрагентПечать = ТЗ.Контрагент;
    
    // Выводим очередную строку в табличный документ
    Таб.ВывестиСекцию("Строка");
    
КонецЦикла;

// Финальное объединение для последней группы после завершения цикла
КонецОбъединения = Таб.ВысотаТаблицы();
Если КонецОбъединения > НачалоОбъединения Тогда
    Таб.Область(НачалоОбъединения, НомерКолонкиАдреса, КонецОбъединения, НомерКолонкиАдреса).Объединить();
КонецЕсли;

// Настраиваем режим просмотра и выводим таблицу на экран
Таб.ТолькоПросмотр(1);
Таб.Показать("Печать документов по адресам");

Восстановление рамок и оформление ячеек

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

Для этого используется метод Рамка() объекта Область. Разберем пример, как вернуть стандартную тонкую сетку по периметру объединенной области:


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

// Назначаем рамки: тип линии 1 (тонкая линия) для всех сторон
// Параметры метода Рамка(Лев, Прав, Верх, Низ)
ОбластьДляОбъединения.Рамка(1, 1, 1, 1);

Параметры метода Рамка() задают тип линии для левой, правой, верхней и нижней границ области соответственно. Значение 1 соответствует сплошной тонкой линии, 0 — отсутствию линии, а 2 — жирной линии.

Подводные камни вертикального объединения в 1С 7.7

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

Альтернатива: Иерархический вывод данных

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

Для этого в макете создаются две горизонтальные секции:

  1. Секция_Группа (например, "Адрес"): Содержит одну ячейку во всю ширину таблицы с фоновым выделением, где выводится название адреса доставки.
  2. Секция_Детали (например, "Строка"): Содержит детальную информацию (Контрагент, Номер документа, Сумма), которая выводится под строкой группы с небольшим визуальным отступом вправо.

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

← На главную