При разработке и адаптации типовых решений на базе 1С:Комплексная автоматизация (КА) или 1С:ERP часто возникает задача вывода специфических данных в печатные формы. Одной из таких задач является вывод дополнительного реквизита, который был создан пользователем в режиме «1С:Предприятие», непосредственно в бланк счета на оплату или любого другого первичного документа. Рассмотрим подробно, как это реализовать, проанализируем типичные ошибки и разберем правильные методы работы с программным кодом.
Основная сложность, с которой сталкиваются начинающие разработчики и аналитики, заключается в непонимании того, где именно исполняется код печати. В современных конфигурациях на управляемых формах логика формирования печатных форм вынесена в Модуль менеджера документа. Разберем ключевое отличие: в отличие от модуля объекта, модуль менеджера «не знает» о конкретной ссылке на документ через ключевое слово ЭтотОбъект или Ссылка. Данные передаются в процедуру печати извне, обычно в виде массива ссылок МассивОбъектов.
Посмотрим на типичную ошибку из практики: попытка обратиться к ДокументСсылка.ТекущийДокумент внутри модуля менеджера приводит к ошибке Переменная не определена. Это происходит потому, что контекст менеджера является глобальным для данного типа объекта, а не для конкретного экземпляра документа в базе данных.
Самый простой и правильный путь для получения значения дополнительного реквизита — использование механизмов общего модуля УправлениеСвойствами. Этот модуль входит в состав БСП и предназначен специально для работы с дополнительными реквизитами и сведениями. Разберем по шагам, как получить значение конкретного свойства.
Для начала нам необходимо найти саму ссылку на дополнительный реквизит (объект ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения). Делать это лучше по его уникальному идентификатору (имени), который задается при создании. Рассмотрим пример кода:
// 1. Находим ссылку на само свойство (реквизит)
ИмяРеквизита = "ДатаИсполненияЗаказа_cb85b7049ecf49b78e5150a610da5b33";
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", ИмяРеквизита);
// 2. Получаем значение этого свойства для конкретного документа
// Предположим, переменная СсылкаНаДокумент — это элемент из МассивОбъектов
ЗначениеСвойства = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаДокумент, СвойствоСсылка);
// 3. Выводим в параметр области макета
ОбластьМакета.Параметры.ДатаИзготовленияТовара = ЗначениеСвойства;
Этот метод хорош своей лаконичностью, однако проанализируем ситуацию с точки зрения производительности. Если пользователь решит распечатать сразу 100 счетов, код в цикле будет выполнять 100 отдельных запросов к базе данных, что существенно замедлит процесс. Рассмотрим более эффективный метод.
Выясним причину, по которой профессиональные разработчики предпочитают запросы. При формировании печатной формы в 1С:КА уже существует основной запрос, который собирает данные для шапки документа (контрагент, сумма, договор). Самый эффективный вариант — интегрировать получение доп. реквизита прямо в этот запрос. Проанализируем структуру хранения: дополнительные реквизиты хранятся в подчиненной табличной части ДополнительныеРеквизиты.
Рассмотрим пример построения запроса с использованием левого соединения:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СчетНаОплату.Ссылка КАК Ссылка,
| СчетНаОплату.Номер КАК Номер,
| СчетНаОплату.Дата КАК Дата,
| ЕСТЬNULL(СчетДопРеквизиты.Значение, """") КАК ДатаИзготовления
|ИЗ
| Документ.СчетНаОплатуКлиенту КАК СчетНаОплату
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетНаОплатуКлиенту.ДополнительныеРеквизиты КАК СчетДопРеквизиты
| ПО СчетНаОплату.Ссылка = СчетДопРеквизиты.Ссылка
| И СчетДопРеквизиты.Свойство = &СвойствоСсылка
|ГДЕ
| СчетНаОплату.Ссылка В(&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Запрос.УстановитьПараметр("СвойствоСсылка", СвойствоСсылка);
РезультатЗапроса = Запрос.Выполнить();
Важный момент: если дополнительный реквизит находится не в самом Счете, а в документе-основании (например, в Заказе клиента), в соединении необходимо использовать путь СчетНаОплату.ЗаказКлиента.ДополнительныеРеквизиты. Это позволит вытащить данные «через точку» от основного документа.
После того как данные получены, их нужно передать в табличный документ. Разберем по шагам процесс взаимодействия с макетом:
ОбластьДанные.Область.Параметры.Заполнить(СтрокаДанных) — отличный способ, если имена полей в запросе совпадают с именами параметров в макете.Формат(), чтобы в печатной форме она выглядела презентабельно (например, "ДФ=dd.MM.yyyy").ТабличныйДокумент.Вывести(Область) добавит подготовленные данные в финальную форму.Проанализируем ситуацию, описанную в сообщениях форума. Пользователь пытался использовать ПланВидовХарактеристикСсылка — это системный тип, а не ссылка на конкретный элемент. Правильно обращаться через менеджер объекта: ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию(...) или НайтиПоРеквизиту("Имя", ...).
Также важно помнить, что дополнительные реквизиты могут быть не заполнены. Всегда проверяйте результат на NULL в запросах или используйте проверку ЗначениеЗаполнено() в коде, чтобы избежать вывода пустых строк или странных значений типа "01.01.0001".
Мы рассмотрели два основных способа решения задачи: быстрый (через БСП) и производительный (через запрос). Для разовых правок аналитиком подойдет метод с использованием УправлениеСвойствами.ЗначениеСвойства(), но для крупных систем с большим объемом печати предпочтительнее интеграция в основной запрос модуля менеджера. Понимание контекста исполнения кода и структуры хранения доп. реквизитов — залог успешной настройки любой печатной формы в 1С.