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

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

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

В этой статье мы подробно разберем, почему стандартный метод Вывести() не подходит для решения этой задачи в лоб, и научимся правильно компоновать табличный документ, используя методы Присоединить() и работу с пересечениями областей.

Разбор типичной ошибки: почему циклы не работают последовательно

Рассмотрим ситуацию, с которой столкнулся автор темы. У нас есть два набора данных (например, две таблицы значений) и макет, разделенный на левую и правую части. Типичная, но ошибочная логика выглядит так: сначала запустить цикл по первой таблице и вывести её в левую колонку, а затем запустить второй цикл и вывести его в правую.

Проанализируем пример «неправильного» кода:


ОбластьТоварыЛ = Макет.ПолучитьОбласть("Строка|ЛеваяКолонка");
ОбластьТоварыП = Макет.ПолучитьОбласть("Строка|ПраваяКолонка");

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

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

Выясним причину неудачи: метод Вывести() у объекта ТабличныйДокумент работает по принципу печатной машинки. Как только вызывается эта команда, система переносит «каретку» на начало следующей строки. Поэтому второй цикл просто продолжит выводить данные ниже первого, даже если сама область в макете находится справа.

Правильный подход: использование метода Присоединить()

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

Разберем по шагам алгоритм параллельного вывода:

  1. Определяем максимальное количество строк среди двух наборов данных.
  2. Запускаем один общий цикл по индексу от 0 до максимально возможного.
  3. Внутри цикла сначала используем Вывести() для левой колонки (создаем новую строку).
  4. Затем используем Присоединить() для правой колонки (дополняем созданную строку).

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


// Получаем области (используем пересечение горизонтальной секции "Строка" и вертикальных колонок)
ОбластьЛ = Макет.ПолучитьОбласть("Строка|ЛеваяКолонка");
ОбластьП = Макет.ПолучитьОбласть("Строка|ПраваяКолонка");

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

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

Работа с именованными областями и пересечениями

Важным моментом, упомянутым в обсуждении, является правильная разметка макета. Чтобы гибко управлять выводом, рекомендуется использовать именованные области не только для строк, но и для колонок.

Проанализируем ситуацию: в макете у вас есть горизонтальная область (секция) с именем Строка и две вертикальные области (колонки) с именами ЛеваяКолонка и ПраваяКолонка. В коде вы можете обращаться к ним через символ «вертикальная черта» — |. Это называется получением области на пересечении.

Пример: Макет.ПолучитьОбласть("Строка|ЛеваяКолонка"). Это гарантирует, что вы получите именно ту часть макета, которая находится в нужной строке и в нужных границах колонок. Это критически важно, если у вас в левой и правой частях разное оформление, шрифты или границы ячеек.

Альтернативный метод: прямое заполнение ячеек (R1C1)

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

Рассмотрим пример:


// Заполнение конкретной ячейки по номеру строки и колонки
НомерСтроки = 5;
НомерКолонки = 10;
ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки).Текст = "Данные";

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

Важные рекомендации по оформлению

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

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

← На главную