Как программно вывести разное количество строк в разных колонках табличного документа 1С

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

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

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

Способ 1. Программное объединение ячеек (Vertical Merge)

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

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

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

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


// Инициализируем табличный документ и макет
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");

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

Важный нюанс: при объединении ячеек свойство ВертикальноеПоложение лучше устанавливать в значение ВертикальноеПоложение.Верх или ВертикальноеПоложение.Центр, чтобы текст в левой колонке не «потерялся» внизу большой ячейки.

Способ 2. Использование настроек СКД «Объединять одинаковые»

Если вы строите отчет с помощью Системы Компоновки Данных (СКД), то писать код для объединения ячеек вручную не нужно. В платформе 1С предусмотрен встроенный механизм контроля дублей.

Рассмотрим, как настроить это поведение:

  1. В схеме компоновки данных перейдите на закладку «Настройки».
  2. Выберите группировку или детальные записи, где выводятся ваши данные.
  3. Перейдите на вкладку «Выбранные поля» или «Условное оформление».
  4. Для конкретного поля (например, «Документ») в свойствах можно найти параметр «Объединять одинаковые».
  5. Установите значение в «Истина».

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

Способ 3. Вывод через текстовую переменную с переносами строк

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

Выясним, как это работает на практике:


// Собираем список товаров в одну строку
ТекстСписокТоваров = "";
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
    ТекстСписокТоваров = ТекстСписокТоваров + СтрокаТЧ.Номенклатура + " - " + СтрокаТЧ.Количество + Символы.ПС;
КонецЦикла;

// Убираем последний лишний перенос строки
ТекстСписокТоваров = СокрЛП(ТекстСписокТоваров);

// Заполняем область макета
ОбластьМакета = Макет.ПолучитьОбласть("Данные");
ОбластьМакета.Параметры.Документ = ДокументСсылка;
ОбластьМакета.Параметры.СписокТоваров = ТекстСписокТоваров;

// ВАЖНО: в макете у ячейки СписокТоваров свойство "Размещение" 
// должно стоять "Переносить"
ТабДок.Вывести(ОбластьМакета);

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

Способ 4. Метод «Присоединить» для динамических колонок

Если задача стоит более сложно — например, нужно выводить данные не просто в две колонки, а динамически наращивать таблицу вправо, — мы используем метод Присоединить(). Однако стоит помнить, что Присоединить() добавляет область в ту же самую строку. Чтобы реализовать «разное количество строк», придется комбинировать методы.

Рассмотрим логику:

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

Этот метод считается более трудоемким и требует филигранной настройки границ ячеек, чтобы пустые ячейки слева не выглядели «дырками» в таблице.

Способ 5. Визуальная имитация (управление границами)

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

Проанализируем преимущества:

Для реализации этого метода в коде нужно проверять, совпадает ли текущий объект с предыдущим. Если совпадает — устанавливаем тип линии ТипЛинииЯчейкиТабличногоДокумента.НетЛинии для верхней границы текущей ячейки.

Рекомендации по интерактивности и расшифровке

Независимо от выбранного метода, не забывайте про удобство пользователя. Если вы используете программное объединение, убедитесь, что вся объединенная область имеет заполненный ПараметрРасшифровки. Это позволит пользователю дважды кликнуть в любом месте «высокой» ячейки документа и открыть его форму.

При использовании метода Символы.ПС (Способ 3) расшифровка будет работать только для всей группы товаров сразу. Если же нужно открывать карточку каждого конкретного товара по отдельности, то единственным верным решением будет Способ 1 (Объединение) или Способ 2 (СКД).

← На главную