При формировании сложных печатных форм в 1С часто возникает задача вывода данных из нескольких источников. Одной из классических проблем является ситуация, когда нам необходимо вывести две таблицы значений (ТЗ) в один табличный документ, при этом количество строк в этих таблицах не совпадает. Если подойти к решению этой задачи прямолинейно, можно столкнуться с эффектом «лесенки» или появлением нежелательных пустых строк. В этой статье мы подробно разберем, как правильно реализовать вывод двух ТЗ, проанализируем ошибки и рассмотрим различные способы компоновки данных.
Рассмотрим ситуацию, описанную пользователем. При попытке вывести две таблицы последовательно, используя два отдельных цикла, автор столкнулся с тем, что данные отображаются некорректно. Давайте проанализируем исходный код, который привел к ошибке:
Для Индекс = 1 По Макс Цикл
Если ТабличноеПоле_1.Количество() >= Индекс Тогда
ОбластьМакета = МакетДокумента.ПолучитьОбласть("Область_Строка1");
ОбластьМакета.Parameters.ФИО_1 = ТабличноеПоле_1[Индекс-1].КолонкаФИО;
ТабДокумент.Вывести(ОбластьМакета);
КонецЕсли;
КонецЦикла;
Для Индекс = 1 По Макс Цикл
Если ТабличноеПоле_2.Количество() >= Индекс Тогда
ОбластьМакета = МакетДокумента.ПолучитьОбласть("ОбластьНД_Строка1");
ОбластьМакета.Parameters.ФИО_2 = ТабличноеПоле_2[Индекс-1].КолонкаФИО;
ТабДокумент.Вывести(ОбластьМакета);
КонецЕсли;
КонецЦикла;
В данном примере используется метод Вывести(). Этот метод всегда добавляет новую область вниз текущего табличного документа. Если области Область_Строка1 и ОбластьНД_Строка1 в макете настроены как горизонтальные секции, то вторая таблица всегда будет начинаться строго под первой. Если же автор ожидал, что таблицы будут стоять рядом, то такая реализация в корне неверна.
Важный момент: если в макете области определены не как целые строки, а как блоки ячеек, то при последовательном выводе 1С может пытаться сохранить структуру колонок, что и приводит к визуальным разрывам. Выясним, как сделать вывод правильно в зависимости от требуемого расположения таблиц.
Это самый простой вариант. Чтобы таблицы выглядели аккуратно, нам нужно убедиться, что области в макете являются горизонтальными секциями. Рассмотрим пошаговый алгоритм:
ШапкаТЗ1, СтрокаТЗ1, ШапкаТЗ2 и СтрокаТЗ2.ТаблицаЗначений и выведем строки.ТаблицаЗначений.Проанализируем правильный код для вертикального вывода:
// Вывод первой таблицы
ОбластьШапка = Макет.ПолучитьОбласть("ШапкаТЗ1");
ТабДок.Вывести(ОбластьШапка);
ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТЗ1");
Для Каждого СтрокаДанных Из ТЗ1 Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаДанных);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
// Разделитель или отступ (по желанию)
ТабДок.Вывести(Макет.ПолучитьОбласть("Разделитель"));
// Вывод второй таблицы
ОбластьШапка = Макет.ПолучитьОбласть("ШапкаТЗ2");
ТабДок.Вывести(ОбластьШапка);
ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТЗ2");
Для Каждого СтрокаДанных Из ТЗ2 Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаДанных);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Использование функции ЗаполнитьЗначенияСвойств позволяет нам автоматически сопоставить имена колонок ТЗ с именами параметров в макете, что делает код чище и профессиональнее.
Если задача — расположить таблицы бок о бок, нам потребуется метод Присоединить(). Основная сложность здесь заключается в том, что количество строк в таблицах разное. Мы должны идти по строкам в одном общем цикле, ориентируясь на максимальное количество строк среди двух таблиц.
Разберем алгоритм по шагам:
Макс().Вывести(), для второй — Присоединить().Посмотрим на пример реализации:
КолСтрок1 = ТЗ1.Количество();
КолСтрок2 = ТЗ2.Количество();
МаксИндекс = Макс(КолСтрок1, КолСтрок2) - 1;
Для Инд = 0 По МаксИндекс Цикл
// Работаем с первой таблицей
ОбластьЛевая = Макет.ПолучитьОбласть("СтрокаТЗ1");
Если Инд < КолСтрок1 Тогда
ЗаполнитьЗначенияСвойств(ОбластьЛевая.Параметры, ТЗ1[Инд]);
Иначе
// Очищаем параметры, чтобы вывести пустую отформатированную ячейку
ОбластьЛевая.Параметры.ФИО_1 = "";
КонецЕсли;
ТабДок.Вывести(ОбластьЛевая);
// Присоединяем вторую таблицу
ОбластьПравая = Макет.ПолучитьОбласть("СтрокаТЗ2");
Если Инд < КолСтрок2 Тогда
ЗаполнитьЗначенияСвойств(ОбластьПравая.Параметры, ТЗ2[Инд]);
Иначе
ОбластьПравая.Параметры.ФИО_2 = "";
КонецЕсли;
ТабДок.Присоединить(ОбластьПравая);
КонецЦикла;
Важно: Метод Присоединить() присоединяет область справа от последней выведенной области Вывести(). Если вы забудете вывести пустую область для таблицы, которая закончилась раньше, верстка «поплывет».
Рассмотрим более продвинутый и гибкий метод, который часто применяют опытные разработчики. Мы можем сформировать каждую таблицу в отдельный объект ТабличныйДокумент, а затем объединить их в основном документе.
Этот способ незаменим, когда таблицы имеют совершенно разную ширину колонок. В 1С 8.2 и 8.3 при выводе в один документ колонки «подстраиваются» друг под друга. Чтобы этого избежать, мы можем использовать свойство Создавать формат строк в макете или метод ВставитьОбласть().
Проанализируем ситуацию: нам нужно вставить вторую таблицу справа от первой. Мы можем сформировать вторую таблицу во временный ТабДокВременный, а затем поместить его содержимое в основной документ в нужные координаты.
При работе с макетами и выводом данных стоит учитывать несколько технических нюансов:
ПроверитьВывод(). Передайте в него массив областей, которые планируете вывести. Если они не помещаются на текущий лист, программно вызовите ВывестиВертикальныйРазделительСтраниц().Область_Данные_Левая). При получении области из макета можно использовать конструкцию Макет.ПолучитьОбласть("R5C1:R5C10"), чтобы точно указать диапазон ячеек, но именованные области предпочтительнее для поддержки кода.Выясним причину ошибки из Сообщения 4 («первые 3 строки заполнены, остальные пустые»). Она возникала из-за того, что автор использовал два последовательных цикла с условием по Макс. В первом цикле выводились строки первой таблицы, а во втором — строки второй. Так как метод Вывести() всегда идет вниз, вторая таблица физически не могла встать рядом с первой. Использование Присоединить() внутри единого цикла полностью решает эту проблему.
Таким образом, мы рассмотрели основные способы вывода нескольких таблиц. Выбор конкретного метода зависит от требований к визуальному представлению отчета и сложности структуры ваших данных.