При формировании печатных форм в системе «1С:Предприятие 7.7» разработчики часто сталкиваются с задачей визуальной оптимизации таблиц. Одной из наиболее распространенных задач является объединение смежных строк с одинаковыми значениями в одной колонке. Например, при выводе реестра документов по разным контрагентам или списка заказов с одинаковыми адресами доставки логично сгруппировать дублирующиеся записи по вертикали. Это делает документ читаемым и аккуратным.
В этой статье мы подробно разберем, как реализовать программное объединение ячеек по вертикали в 1С 7.7, проанализируем алгоритм динамического расчета координат областей, изучим готовый шаблон кода и рассмотрим подводные камни, с которыми можно столкнуться на практике.
Для программного управления ячейками в платформе 1С 7.7 используется встроенный объект Таблица. Чтобы объединить группу ячеек, нам сначала необходимо получить доступ к конкретному диапазону (области) этой таблицы, а затем вызвать соответствующий метод.
Синтаксис получения области выглядит следующим образом:
Таб.Область(Верх, Лево, Низ, Право)
Где параметры принимают числовые значения границ области:
Если нам необходимо объединить ячейки только в одной конкретной колонке по вертикали, параметры Лево и Право будут одинаковыми (будут указывать на номер этой колонки). Непосредственно для слияния ячеек применяется метод Объединить().
Рассмотрим базовый пример: если нам нужно объединить ячейки в первой колонке со строки №5 по строку №10, команда будет выглядеть так:
Таб.Область(5, 1, 10, 1).Объединить();
Важная особенность: При слиянии нескольких ячеек результирующая (объединенная) область сохраняет текстовое значение и параметры форматирования (шрифт, цвет, выравнивание) только из самой верхней левой ячейки исходного диапазона. Данные из всех остальных ячеек, попавших под объединение, будут стерты.
В реальных отчетах количество выводимых строк заранее неизвестно, так как данные берутся динамически из справочников, документов или таблиц значений. Соответственно, мы не можем «зашить» жесткие номера строк в код. Нам необходимо рассчитывать координаты Верх и Низ прямо во время вывода секций.
Давайте детально разберем алгоритм решения этой задачи:
НачалоОбъединения. Ее начальное значение должно быть равно номеру первой строки, которая будет выведена в табличную часть (ее можно определить как Таб.ВысотаТаблицы() + 1 после вывода шапки).ТекущийАдрес = "").КонецОбъединения = Таб.ВысотаТаблицы().КонецОбъединения строго больше, чем НачалоОбъединения, это означает, что в группе накопилось две или более строк. В этом случае мы вызываем метод Объединить() для накопленной области.НачалоОбъединения на следующую строку (которая сейчас будет выводиться): Таб.ВысотаТаблицы() + 1, и обновляем значение переменной ТекущийАдрес.НачалоОбъединения до текущей высоты таблицы.Давайте посмотрим на практический пример кода, написанный на встроенном языке 1С 7.7. Предположим, у нас есть заполненная таблица значений ТЗ с колонками АдресДоставки и Контрагент. Наша задача — вывести эти данные в макет и объединить строки по одинаковым адресам в первой колонке.
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Макет");
Таб.ВывестиСекцию("Шапка"); // Вывели шапку отчета
// Определяем номер целевой колонки для объединения (например, первая колонка)
НомерКолонкиАдреса = 1;
// Инициализируем начальные координаты
НачалоОбъединения = Таб.ВысотаТаблицы() + 1;
ТекущийАдрес = "";
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
// Проверяем, изменился ли адрес по сравнению с предыдущей строкой
Если (ТЗ.АдресДоставки <> ТекущийАдрес) И (ТекущийАдрес <> "") Тогда
КонецОбъединения = Таб.ВысотаТаблицы();
// Объединяем область, если в ней накопилось больше одной строки
Если КонецОбъединения > НачалоОбъединения Тогда
Таб.Область(НачалоОбъединения, НомерКолонкиАдреса, КонецОбъединения, НомерКолонкиАдреса).Объединить();
КонецЕсли;
// Устанавливаем точку отсчета для следующей уникальной группы
НачалоОбъединения = Таб.ВысотаТаблицы() + 1;
КонецЕсли;
// Запоминаем текущее значение для последующих сравнений
ТекущийАдрес = ТЗ.АдресДоставки;
// Заполняем параметры секции "Строка"
АдресПечать = ТЗ.АдресДоставки;
КонтрагентПечать = ТЗ.Контрагент;
// Выводим очередную строку в табличный документ
Таб.ВывестиСекцию("Строка");
КонецЦикла;
// Финальное объединение для последней группы после завершения цикла
КонецОбъединения = Таб.ВысотаТаблицы();
Если КонецОбъединения > НачалоОбъединения Тогда
Таб.Область(НачалоОбъединения, НомерКолонкиАдреса, КонецОбъединения, НомерКолонкиАдреса).Объединить();
КонецЕсли;
// Настраиваем режим просмотра и выводим таблицу на экран
Таб.ТолькоПросмотр(1);
Таб.Показать("Печать документов по адресам");
Довольно частой проблемой при программном объединении ячеек в платформе 1С 7.7 является «ломающаяся» сетка таблицы. После вызова метода Объединить() внутренние границы объединенной области исчезают, а внешние рамки могут начать отображаться некорректно (например, стать тонкими или пропасть вовсе). Чтобы таблица сохранила профессиональный и аккуратный вид, рекомендуется принудительно восстанавливать рамки для объединенного диапазона.
Для этого используется метод Рамка() объекта Область. Разберем пример, как вернуть стандартную тонкую сетку по периметру объединенной области:
ОбластьДляОбъединения = Таб.Область(НачалоОбъединения, НомерКолонкиАдреса, КонецОбъединения, НомерКолонкиАдреса);
ОбластьДляОбъединения.Объединить();
// Назначаем рамки: тип линии 1 (тонкая линия) для всех сторон
// Параметры метода Рамка(Лев, Прав, Верх, Низ)
ОбластьДляОбъединения.Рамка(1, 1, 1, 1);
Параметры метода Рамка() задают тип линии для левой, правой, верхней и нижней границ области соответственно. Значение 1 соответствует сплошной тонкой линии, 0 — отсутствию линии, а 2 — жирной линии.
Опытные разработчики 1С 7.7 знают, что злоупотреблять вертикальным объединением строк в печатных формах не стоит. Платформа имеет ряд архитектурных ограничений, которые могут привести к неожиданным визуальным дефектам:
.xls часто приводит к искажению структуры файла. Более того, конечным пользователям будет крайне неудобно работать с таким файлом в Excel: в нем перестанут корректно работать стандартные инструменты фильтрации, сортировки данных и построения сводных таблиц.Если вы понимаете, что печатная форма будет содержать сотни строк, а пользователи планируют выгружать ее в Excel, лучше отказаться от вертикального объединения ячеек в пользу горизонтальной группировки (иерархического вывода).
Для этого в макете создаются две горизонтальные секции:
При таком подходе структура документа получается линейной, платформа идеально рассчитывает перенос страниц, а при экспорте в Excel данные сохраняют строгую табличную форму, удобную для последующей обработки и фильтрации.