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