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

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

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

Способ 1. Программное объединение диапазона ячеек через метод Объединить()

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

Разберем по шагам логику реализации при обходе выборки запроса с группировками:

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

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


// Получаем макет и области
Макет = ПолучитьМакет("Макет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

ТабДок.Вывести(ОбластьШапка);

ВыборкаСклад = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

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

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

Ограничения и нюансы вертикального объединения ячеек

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

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

Способ 2. Псевдообъединение через скрытие горизонтальных границ

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

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


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

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

Способ 3. Реализация средствами Системы компоновки данных (СКД)

Если отчет разрабатывается с использованием СКД, писать программный код для объединения ячеек не требуется. Подобное представление настраивается штатными средствами схемы компоновки:

  1. В настройках структуры отчета создаем группировку Склад, а внутри нее — группировку Номенклатура (или Детальные записи).
  2. Переходим на вкладку Другие настройки (как для всего отчета, так и для конкретной группировки).
  3. Для параметра Расположение полей группировок устанавливаем значение Отдельно и только в итогах или Отдельно.
  4. В этом случае СКД автоматически выведет колонку группировки рядом с детальными записями и применит стандартное объединение повторяющихся значений без необходимости ручного программирования макета.
← На главную