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