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