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