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