Как вывести нужную область макета печатной формы по значению реквизита в 1С 8.3

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

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

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

Причина возникновения ошибки в модуле менеджера

Проанализируем ситуация, когда на форме документа добавлен переключатель (тумблер), связанный с реквизитом документа ЛокальнаяСетевая (например, со значениями 1 — Локальная, 2 — Сетевая). При попытке обратиться к этому переключателю напрямую в модуле менеджера возникает ошибка.

Причины такого поведения платформы следующие:

  1. Разделение контекстов: Модуль менеджера выполняется строго на сервере. В нем полностью отсутствуют контекст формы (объект Элементы) и контекст объекта (переменная ЭтотОбъект).
  2. Данные базы данных: Если значение реквизита находится в форме, но документ еще не записан или реквизит не добавлен в запрос печатной формы, модуль менеджера «не знает» о существовании этого значения.

Решение 1. Получение реквизита через запрос и условие «Если... ИначеЕсли»

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

Разберем пример кода алгоритма печати:


// 1. Получаем макет документа
Макет = УправлениеПечатью.МакетПечатнойФормы("Документ.МойДокумент.ПФ_MXL_ПечатнаяФорма");

// 2. Формируем запрос для получения данных документа
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	МойДокумент.Ссылка КАК Ссылка,
    |	МойДокумент.ЛокальнаяСетевая КАК ЛокальнаяСетевая
    |ИЗ
    |	Документ.МойДокумент КАК МойДокумент
    |ГДЕ
    |	МойДокумент.Ссылка В(&МассивДокументов)";

Запрос.УстановитьПараметр("МассивДокументов", МассивОбъектов);
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

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

    // Заполняем параметры области и выводим в табличный документ
    ТабличныйДокумент.Вывести(ОбластьМакета);

КонецЦикла;

Решение 2. Динамическое получение области по имени

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

Плюсом этого метода является отсутствие громоздких конструкций Если... ИначеЕсли, особенно когда вариантов переключателя много.

Пример динамического обращения к области макета:


Пока Выборка.Следующий() Цикл

    // Имя области формируется динамически: "Обл" + 1 или "Обл" + 2
    ИмяОбласти = "Обл" + Строка(Выборка.ЛокальнаяСетевая);
    
    ОбластьМакета = Макет.ПолучитьОбласть(ИмяОбласти);
    ТабличныйДокумент.Вывести(ОбластьМакета);

КонецЦикла;

Рекомендации по чистой разработке в 1С

Чтобы избежать ошибок при выводе печатных форм и сделать код надежным, учтем следующие правила:

  1. Перечисления вместо Чисел: Использовать реквизиты с типом Число (1, 2, 3) для обозначения режимов работы не рекомендуется. Создайте объект метаданных ПеречислениеRef (например, ТипыПодключения со значениями Локальная и Сетевая). Это защитит код от случайных ошибок при сравнении значений.
  2. Проверка метода Следующий(): Всегда вызывайте Выборка.Следующий() перед обращением к полям выборки запроса. Без этого вызов Выборка.ЛокальнаяСетевая вызовет ошибку обращения к значению.
  3. Передача параметров формы: Если переключатель на форме является временным реквизитом формы (не сохраняется в базе), его значение нужно передавать в печатную форму через структуру ПараметрыПечати.
← На главную