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

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

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

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

Способ 1. Использование единого многострочного параметра (метод "Шаблон")

Это самый простой в реализации метод, который идеально подходит, если данных в правой "проблемной" части немного (например, до 5–10 строк исполнителей). Суть заключается в том, чтобы в макете создать одну ячейку, которая будет вмещать в себя все строки из второй таблицы.

Проанализируем алгоритм реализации этого метода:

  1. В макете печатной формы создаем область. В правой части этой области объединяем несколько строк в одну большую ячейку (или просто оставляем одну ячейку, если высота строки будет регулироваться автоматически).
  2. Называем эту ячейку, например, ШаблонИсполнителей. В свойствах ячейки обязательно устанавливаем параметр Размещение текста в значение Переносить.
  3. В коде формирования печатной формы сначала собираем данные из табличной части в одну строковую переменную, разделяя записи символом переноса строки Символы.ПС.

Рассмотрим пример кода для реализации этого подхода:


// Инициализируем переменную для хранения списка исполнителей
ТекстИсполнителей = "";

// Обходим табличную часть исполнителей (например, из выборки или напрямую из ТЧ документа)
Для Каждого СтрокаИсполнитель Из СсылкаНаОбъект.Исполнители Цикл
    // Формируем строку: Имя + Коэффициент
    ТекущаяСтрока = СтрокаИсполнитель.Сотрудник.Наименование + " (коэф. " + СтрокаИсполнитель.Коэффициент + ")";
    
    // Добавляем к общему тексту с разделителем, если строка не первая
    ТекстИсполнителей = ТекстИсполнителей + ?(ПустаяСтрока(ТекстИсполнителей), "", Символы.ПС) + ТекущаяСтрока;
КонецЦикла;

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

Этот метод хорош тем, что 1С автоматически расширит высоту всей строки макета под размер самого длинного текста (если установлено свойство Автовысота строки). Однако он не позволяет рисовать сложные рамки вокруг каждого исполнителя в отдельности, так как по сути это одна ячейка с текстом.

Способ 2. Синхронный вывод строк (Параллельный обход)

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

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

  1. Создаем в макете две горизонтальные области: ОбластьЛево и ОбластьПраво.
  2. В коде определяем максимальное количество строк среди двух таблиц.
  3. Запускаем цикл по этому максимальному числу.
  4. Внутри цикла сначала выводим левую часть методом Вывести(), а затем "приклеиваем" правую часть методом Присоединить().

Проанализируем пример кода:


// Предположим, у нас есть две таблицы: ТЗ_Товары и ТЗ_Исполнители
МаксСтрок = Макс(ТЗ_Товары.Количество(), ТЗ_Исполнители.Количество());

Для НомерСтроки = 0 По МаксСтрок - 1 Цикл
    
    // Получаем области заново в каждой итерации (чтобы параметры были чистыми)
    ОблЛево = Макет.ПолучитьОбласть("СтрокаТовара");
    ОблПраво = Макет.ПолучитьОбласть("СтрокаИсполнителя");
    
    // Заполняем левую часть, если данные еще есть
    Если НомерСтроки < ТЗ_Товары.Количество() Тогда
        ТекущийТовар = ТЗ_Товары[НомерСтроки];
        ОблЛево.Параметры.Заполнить(ТекущийТовар);
    Иначе
        // Если товаров меньше, чем исполнителей, выводим "пустую" область для сохранения структуры
        ОблЛево.Параметры.Очистить(); 
    КонецЕсли;
    
    // Сначала ВЫВОДИМ левую часть
    ТабДок.Вывести(ОблЛево);
    
    // Заполняем правую часть
    Если НомерСтроки < ТЗ_Исполнители.Количество() Тогда
        ТекущийИсполнитель = ТЗ_Исполнители[НомерСтроки];
        ОблПраво.Параметры.Заполнить(ТекущийИсполнитель);
    Иначе
        ОблПраво.Параметры.Очистить();
    КонецЕсли;
    
    // Теперь ПРИСОЕДИНЯЕМ правую часть к только что выведенной левой
    ТабДок.Присоединить(ОблПраво);
    
КонецЦикла;

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

Способ 3. Использование промежуточного (буферного) табличного документа

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

Разберем этот алгоритм:

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

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

Особенности оформления и настройки макета

Когда мы выводим две области рядом, часто возникают визуальные дефекты. Посмотрим, как их избежать:

  1. Границы ячеек: Если и у левой, и у правой области установлены все границы (обводка), то в месте их стыка линия будет двойной толщины. Чтобы этого не происходило, в макете у левой области уберите правую границу, а у правой — оставьте все.
  2. Автовысота строк: Если вы используете метод Присоединить(), помните: высота строки в результирующем документе будет определяться по самой высокой ячейке в этой строке (либо слева, либо справа). Это нужно учитывать при верстке.
  3. Фиксация колонок: Чтобы печатная форма не превратилась в "кашу" при печати на листе А4, задайте жесткую ширину колонок для обеих частей в макете. Проверьте, чтобы суммарная ширина левой и правой части не превышала ширину области печати.

Заключение

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

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

← На главную