При разработке отчетов в системе 1С:Предприятие далеко не всегда используется Система компоновки данных (СКД). В старых конфигурациях, при доработке сложных печатных форм или создании узкоспециализированных инструментов на базе построителя отчетов, программисты часто сталкиваются с задачей динамического добавления колонок. Например, когда количество столбцов зависит от выбранного пользователем периода (месяцы) или количества складов.
В этой статье мы подробно разберем, как правильно реализовать вывод данных «вправо», используя механизмы работы с табличным документом, и как избежать типичных ошибок при формировании макета.
Основным инструментом для расширения таблицы в горизонтальном направлении является метод Присоединить(). В отличие от метода Вывести(), который добавляет новую область снизу (переводя курсор на новую строку), метод Присоединить() располагает указанную область справа от уже выведенных данных в той же строке.
Однако простого вызова метода недостаточно. Если мы попробуем присоединить целую вертикальную секцию к уже выведенной горизонтальной строке, мы можем столкнуться с нарушением форматирования. Разберем, как этого избежать.
Для корректного формирования сложного отчета нам необходимо работать с «пересечениями». Рассмотрим ситуацию: у нас есть горизонтальная секция «Строка» и вертикальная секция «КолонкаДанных». Чтобы вывести конкретную ячейку на их пересечении, мы используем конструкцию:
Область = Макет.ПолучитьОбласть("Строка|КолонкаДанных");
Почему это важно: такой подход позволяет получить область, ограниченную и по высоте (из горизонтальной секции), и по ширине (из вертикальной). Это гарантирует, что при выполнении ТабДок.Присоединить(Область) данные попадут ровно в нужную строку и не «раздуют» таблицу лишними пустыми ячейками сверху или снизу.
Проанализируем классическую схему программного кода для вывода динамических колонок. Представим, что в запросе мы использовали предложение ИТОГИ по периодам или аналитике, которую хотим видеть в колонках.
Посмотрим на пример логики формирования строки:
// 1. Выводим фиксированную левую часть (например, Номенклатура)
ОбластьЛево = Макет.ПолучитьОбласть("Строка|ШапкаСтрок");
ТабДок.Вывести(ОбластьЛево);
// 2. Начинаем цикл по динамическим колонкам (например, по месяцам)
Пока ВыборкаПериод.Следующий() Цикл
// Получаем область на пересечении текущей строки и динамической колонки
ОбластьКолонка = Макет.ПолучитьОбласть("Строка|ДинамическаяКолонка");
// Заполняем параметры данными из выборки
ОбластьКолонка.Параметры.Заполнить(ВыборкаПериод);
// Присоединяем справа в ту же строку
ТабДок.Присоединить(ОбластьКолонка);
КонецЦикла;
После завершения цикла по колонкам управление возвращается к началу основного цикла по строкам, где следующий вызов Вывести() создаст новую строку под текущей.
Чтобы отчет был не только информативным, но и удобным, мы можем программно добавить возможность сворачивания групп колонок (знакомые всем «плюсики»). Для этого используются специальные методы табличного документа.
Рассмотрим порядок действий для создания группировки:
ТабДок.НачатьГруппировкуКолонок().Присоединить().ТабДок.ЗакончитьГруппировкуКолонок().Это позволяет пользователю анализировать как детальные данные по каждому дню, так и сводные итоги за месяц, просто свернув ненужные в данный момент столбцы.
При формировании больших отчетов обращение к каждому параметру области по отдельности (через Область.Параметры.Имя = Значение) может существенно замедлить процесс. Выясним, как ускорить этот процесс.
Эффективнее всего называть параметры в макете точно так же, как поля в выборке вашего запроса. В этом случае мы можем использовать метод Заполнить():
Область.Параметры.Заполнить(ВыборкаИзЗапроса);
Этот метод работает на уровне платформы значительно быстрее, чем множественное присвоение значений вручную.
Когда колонок становится много, пользователю становится неудобно прокручивать отчет — названия строк скрываются за левым краем экрана. Проанализируем, как закрепить левую часть отчета.
Используйте свойство табличного документа ФиксацияСлева. В нем нужно указать количество колонок, которые всегда должны оставаться видимыми:
ТабДок.ФиксацияСлева = 2; // Например, закрепляем код и наименование
Также важно помнить о ширине колонок. При динамическом присоединении области принимают ту ширину, которая задана в макете. Если данные не помещаются, можно включить автоматический расчет ширины для всего отчета после его формирования:
ТабДок.АвтоШиринаКолонок = Истина;
Важный нюанс: автоматический расчет ширины может занимать значительное время на отчетах с десятками тысяч ячеек. В таких случаях лучше заранее установить фиксированную ширину в макете или программно задавать её для конкретных областей.
Разберем ситуацию, которая часто приводит к «поплывшей» структуре таблицы. Если в данных запроса для определенной строки отсутствует значение для одной из динамических колонок, мы все равно обязаны выполнить Присоединить() для этой ячейки (пусть и с пустой областью). Если мы пропустим шаг цикла, то следующая заполненная колонка сместится влево, и данные окажутся под неверным заголовком. Структура вывода должна быть идентичной для каждой строки отчета.
Мы выяснили, что для добавления колонок в отчет без СКД необходимо:
ПолучитьОбласть("Секция1|Секция2") для точного позиционирования.Присоединить() для горизонтального расширения таблицы.Соблюдение этих правил позволит создавать профессиональные и быстродействующие отчеты любой сложности, сохраняя полный контроль над их визуальным представлением.