Как вывести на печать две таблицы значений с разным количеством строк в 1С?

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

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

Анализ проблемы: почему появляются пустые строки

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


Для Индекс = 1 По Макс Цикл
    Если ТабличноеПоле_1.Количество() >= Индекс Тогда
        ОбластьМакета = МакетДокумента.ПолучитьОбласть("Область_Строка1");
        ОбластьМакета.Parameters.ФИО_1 = ТабличноеПоле_1[Индекс-1].КолонкаФИО;
        ТабДокумент.Вывести(ОбластьМакета);
    КонецЕсли;
КонецЦикла;

Для Индекс = 1 По Макс Цикл
    Если ТабличноеПоле_2.Количество() >= Индекс Тогда
        ОбластьМакета = МакетДокумента.ПолучитьОбласть("ОбластьНД_Строка1");
        ОбластьМакета.Parameters.ФИО_2 = ТабличноеПоле_2[Индекс-1].КолонкаФИО;
        ТабДокумент.Вывести(ОбластьМакета);
    КонецЕсли;
КонецЦикла;

В данном примере используется метод Вывести(). Этот метод всегда добавляет новую область вниз текущего табличного документа. Если области Область_Строка1 и ОбластьНД_Строка1 в макете настроены как горизонтальные секции, то вторая таблица всегда будет начинаться строго под первой. Если же автор ожидал, что таблицы будут стоять рядом, то такая реализация в корне неверна.

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

Вариант 1: Вертикальный вывод (одна таблица под другой)

Это самый простой вариант. Чтобы таблицы выглядели аккуратно, нам нужно убедиться, что области в макете являются горизонтальными секциями. Рассмотрим пошаговый алгоритм:

  1. Создадим в макете три области: ШапкаТЗ1, СтрокаТЗ1, ШапкаТЗ2 и СтрокаТЗ2.
  2. Выведем шапку первой таблицы.
  3. Запустим цикл по первой ТаблицаЗначений и выведем строки.
  4. Выведем шапку второй таблицы (она автоматически встанет под первой).
  5. Запустим цикл по второй ТаблицаЗначений.

Проанализируем правильный код для вертикального вывода:


// Вывод первой таблицы
ОбластьШапка = Макет.ПолучитьОбласть("ШапкаТЗ1");
ТабДок.Вывести(ОбластьШапка);

ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТЗ1");
Для Каждого СтрокаДанных Из ТЗ1 Цикл
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаДанных);
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

// Разделитель или отступ (по желанию)
ТабДок.Вывести(Макет.ПолучитьОбласть("Разделитель"));

// Вывод второй таблицы
ОбластьШапка = Макет.ПолучитьОбласть("ШапкаТЗ2");
ТабДок.Вывести(ОбластьШапка);

ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТЗ2");
Для Каждого СтрокаДанных Из ТЗ2 Цикл
    ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, СтрокаДанных);
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Использование функции ЗаполнитьЗначенияСвойств позволяет нам автоматически сопоставить имена колонок ТЗ с именами параметров в макете, что делает код чище и профессиональнее.

Вариант 2: Горизонтальный вывод (таблицы рядом)

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

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

  1. Определим максимальное число итераций с помощью функции Макс().
  2. Внутри цикла будем проверять, существует ли строка с текущим индексом в каждой из таблиц.
  3. Для первой таблицы используем Вывести(), для второй — Присоединить().

Посмотрим на пример реализации:


КолСтрок1 = ТЗ1.Количество();
КолСтрок2 = ТЗ2.Количество();
МаксИндекс = Макс(КолСтрок1, КолСтрок2) - 1;

Для Инд = 0 По МаксИндекс Цикл
    
    // Работаем с первой таблицей
    ОбластьЛевая = Макет.ПолучитьОбласть("СтрокаТЗ1");
    Если Инд < КолСтрок1 Тогда
        ЗаполнитьЗначенияСвойств(ОбластьЛевая.Параметры, ТЗ1[Инд]);
    Иначе
        // Очищаем параметры, чтобы вывести пустую отформатированную ячейку
        ОбластьЛевая.Параметры.ФИО_1 = ""; 
    КонецЕсли;
    ТабДок.Вывести(ОбластьЛевая);
    
    // Присоединяем вторую таблицу
    ОбластьПравая = Макет.ПолучитьОбласть("СтрокаТЗ2");
    Если Инд < КолСтрок2 Тогда
        ЗаполнитьЗначенияСвойств(ОбластьПравая.Параметры, ТЗ2[Инд]);
    Иначе
        ОбластьПравая.Параметры.ФИО_2 = "";
    КонецЕсли;
    ТабДок.Присоединить(ОбластьПравая);
    
КонецЦикла;

Важно: Метод Присоединить() присоединяет область справа от последней выведенной области Вывести(). Если вы забудете вывести пустую область для таблицы, которая закончилась раньше, верстка «поплывет».

Вариант 3: Использование временных табличных документов

Рассмотрим более продвинутый и гибкий метод, который часто применяют опытные разработчики. Мы можем сформировать каждую таблицу в отдельный объект ТабличныйДокумент, а затем объединить их в основном документе.

Этот способ незаменим, когда таблицы имеют совершенно разную ширину колонок. В 1С 8.2 и 8.3 при выводе в один документ колонки «подстраиваются» друг под друга. Чтобы этого избежать, мы можем использовать свойство Создавать формат строк в макете или метод ВставитьОбласть().

Проанализируем ситуацию: нам нужно вставить вторую таблицу справа от первой. Мы можем сформировать вторую таблицу во временный ТабДокВременный, а затем поместить его содержимое в основной документ в нужные координаты.

Тонкости форматирования и оптимизации

При работе с макетами и выводом данных стоит учитывать несколько технических нюансов:

  1. Свойство «Создавать формат строк»: В макете 1С 8.2 выделите строки, относящиеся к разным таблицам, и установите это свойство. Это позволит задать индивидуальную ширину колонок для каждой таблицы, даже если они выводятся вертикально одна под другой.
  2. Проверка вывода на страницу: Если таблицы длинные, используйте метод ПроверитьВывод(). Передайте в него массив областей, которые планируете вывести. Если они не помещаются на текущий лист, программно вызовите ВывестиВертикальныйРазделительСтраниц().
  3. Области макета: Старайтесь называть области понятно (например, Область_Данные_Левая). При получении области из макета можно использовать конструкцию Макет.ПолучитьОбласть("R5C1:R5C10"), чтобы точно указать диапазон ячеек, но именованные области предпочтительнее для поддержки кода.

Выясним причину ошибки из Сообщения 4 («первые 3 строки заполнены, остальные пустые»). Она возникала из-за того, что автор использовал два последовательных цикла с условием по Макс. В первом цикле выводились строки первой таблицы, а во втором — строки второй. Так как метод Вывести() всегда идет вниз, вторая таблица физически не могла встать рядом с первой. Использование Присоединить() внутри единого цикла полностью решает эту проблему.

Таким образом, мы рассмотрели основные способы вывода нескольких таблиц. Выбор конкретного метода зависит от требований к визуальному представлению отчета и сложности структуры ваших данных.

← На главную