Как добавить динамические колонки в отчет 1С без использования СКД?

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

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

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

Понятие метода Присоединить() в работе с макетом

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

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

Механика пересечения областей

Для корректного формирования сложного отчета нам необходимо работать с «пересечениями». Рассмотрим ситуацию: у нас есть горизонтальная секция «Строка» и вертикальная секция «КолонкаДанных». Чтобы вывести конкретную ячейку на их пересечении, мы используем конструкцию:

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

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

Алгоритм вывода отчета (цикл в цикле)

Проанализируем классическую схему программного кода для вывода динамических колонок. Представим, что в запросе мы использовали предложение ИТОГИ по периодам или аналитике, которую хотим видеть в колонках.

Посмотрим на пример логики формирования строки:


// 1. Выводим фиксированную левую часть (например, Номенклатура)
ОбластьЛево = Макет.ПолучитьОбласть("Строка|ШапкаСтрок");
ТабДок.Вывести(ОбластьЛево);

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

После завершения цикла по колонкам управление возвращается к началу основного цикла по строкам, где следующий вызов Вывести() создаст новую строку под текущей.

Управление группировками колонок

Чтобы отчет был не только информативным, но и удобным, мы можем программно добавить возможность сворачивания групп колонок (знакомые всем «плюсики»). Для этого используются специальные методы табличного документа.

Рассмотрим порядок действий для создания группировки:

  1. Перед началом цикла вывода колонок, которые должны входить в группу, вызываем метод ТабДок.НачатьГруппировкуКолонок().
  2. Внутри цикла производим обычное Присоединить().
  3. После завершения вывода данных группы вызываем ТабДок.ЗакончитьГруппировкуКолонок().

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

Оптимизация заполнения параметров

При формировании больших отчетов обращение к каждому параметру области по отдельности (через Область.Параметры.Имя = Значение) может существенно замедлить процесс. Выясним, как ускорить этот процесс.

Эффективнее всего называть параметры в макете точно так же, как поля в выборке вашего запроса. В этом случае мы можем использовать метод Заполнить():

Область.Параметры.Заполнить(ВыборкаИзЗапроса);

Этот метод работает на уровне платформы значительно быстрее, чем множественное присвоение значений вручную.

Фиксация областей и настройка ширины

Когда колонок становится много, пользователю становится неудобно прокручивать отчет — названия строк скрываются за левым краем экрана. Проанализируем, как закрепить левую часть отчета.

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

ТабДок.ФиксацияСлева = 2; // Например, закрепляем код и наименование

Также важно помнить о ширине колонок. При динамическом присоединении области принимают ту ширину, которая задана в макете. Если данные не помещаются, можно включить автоматический расчет ширины для всего отчета после его формирования:

ТабДок.АвтоШиринаКолонок = Истина;

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

Обработка пустых значений

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

Резюме

Мы выяснили, что для добавления колонок в отчет без СКД необходимо:

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

← На главную