Как программно получить значения дополнительных реквизитов характеристик номенклатуры в 1С

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В современных конфигурациях 1С, построенных на базе Библиотеки стандартных подсистем (БСП), механизм дополнительных реквизитов и сведений является основным способом расширения состава данных без изменения структуры метаданных. Часто возникает задача: как получить значение такого реквизита (например, «Длина листа» или «Ширина») программно, чтобы использовать его в расчетах, печатных формах или логике проведения документов. В данной статье мы разберем несколько способов решения этой задачи, начиная от простого перебора табличной части и заканчивая оптимальными запросами и использованием встроенных функций БСП.

Понимание структуры хранения дополнительных реквизитов

Прежде чем переходить к коду, давайте проанализируем, где именно хранятся эти данные. В отличие от обычных реквизитов, которые видны в дереве конфигурации, дополнительные реквизиты располагаются в табличной части практически любого объекта (Справочника или Документа). Эта табличная часть обычно называется ДополнительныеРеквизиты. Она состоит из двух ключевых колонок:

  1. Свойство — ссылка на элемент плана видов характеристик ДополнительныеРеквизитыИСведения.
  2. Значение — собственно данные, которые ввел пользователь (число, строка, дата или ссылка).

Важно не путать Дополнительные реквизиты с Дополнительными сведениями. Реквизиты хранятся «внутри» объекта (в его табличной части), а сведения — «снаружи» (в регистре сведений ДополнительныеСведения).

Способ 1: Получение значения из ссылки (через перебор табличной части)

Если у нас уже есть ссылка на характеристику номенклатуры и нам нужно быстро получить значение одного конкретного свойства, мы можем воспользоваться методом Найти() для табличной части. Рассмотрим пример кода, который позволяет извлечь числовое значение «Длины листа»:


// Предположим, что ХарактеристикаСсылка — это ссылка на Справочник.ХарактеристикиНоменклатуры
// А СвойствоСсылка — это ссылка на элемент ПланаВидовХарактеристик.ДополнительныеРеквизитыИСведения

СтрокаДопРеквизита = ХарактеристикаСсылка.ДополнительныеРеквизиты.Найти(СвойствоСсылка, "Свойство");

Если СтрокаДопРеквизита <> Неопределено Тогда
    ЗначениеРеквизита = СтрокаДопРеквизита.Значение;
    // Теперь переменная ЗначениеРеквизита содержит наше число (например, 5.35)
Иначе
    ЗначениеРеквизита = 0; // Свойство не заполнено
КонецЕсли;

Этот метод прост, но имеет важную особенность: при обращении через точку ХарактеристикаСсылка.ДополнительныеРеквизиты система неявно считывает весь объект из базы данных. Если вам нужно получить данные для одного объекта — это допустимо. Если же вы работаете в цикле с сотнями товаров, такой подход крайне негативно скажется на производительности.

Способ 2: Использование стандартных функций БСП (Рекомендуемый)

В конфигурациях вроде УТ 11, ERP 2 или КА 2 реализован программный интерфейс для работы со свойствами. Вместо того чтобы вручную искать строки в табличных частях, мы можем вызвать функцию общего модуля УправлениеСвойствами. Это делает код более читаемым и защищенным от изменений в структуре метаданных. Для быстрого поиска и изучения подобных стандартных функций можно использовать справочник по методам БСП с примерами использования.

Для получения одного значения используем следующую конструкцию:


// Получаем значение свойства "Длина листа"
Значение = УправлениеСвойствами.ЗначениеСвойства(ХарактеристикаСсылка, СвойствоСсылка);

Если же нам требуется получить сразу несколько реквизитов (например, длину, ширину и количество), эффективнее получить их все одним вызовом в структуру:


// Получаем все заполненные дополнительные реквизиты объекта
СтруктураСвойств = УправлениеСвойствами.ЗначенияСвойств(ХарактеристикаСсылка);

// Обращаемся к конкретному свойству по ссылке
Если СтруктураСвойств.Свойство(СвойствоСсылка) Тогда
    Длина = СтруктураСвойств[СвойствоСсылка];
КонецЕсли;

Способ 3: Получение данных через запрос (Оптимальный для списков)

Разберем ситуацию, когда нам нужно вывести дополнительные реквизиты для целого списка характеристик (например, в отчете или при заполнении табличной части заказа). В этом случае использование методов в цикле недопустимо. Нам поможет Запрос. Проанализируем, как правильно соединить основную таблицу с таблицей дополнительных реквизитов.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Характеристики.Ссылка КАК Характеристика,
    |	ЕСТЬNULL(ДопРеквизиты.Значение, 0) КАК ДлинаЛиста
    |ИЗ
    |	Справочник.ХарактеристикиНоменклатуры КАК Характеристики
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ДопРеквизиты
    |		ПО ДопРеквизиты.Ссылка = Характеристики.Ссылка
    |			И ДопРеквизиты.Свойство = &ЦелевоеСвойство
    |ГДЕ
    |	Характеристики.Владелец = &Номенклатура";

Запрос.УстановитьПараметр("ЦелевоеСвойство", СвойствоСсылка);
Запрос.УстановитьПараметр("Номенклатура", СсылкаНаНоменклатуру);

РезультатЗапроса = Запрос.Выполнить();

Важный нюанс: Обратите внимание, что условие по свойству ДопРеквизиты.Свойство = &ЦелевоеСвойство вынесено в секцию ПО левого соединения. Это критически важно. Если вы перенесете это условие в секцию ГДЕ, характеристики, у которых данный реквизит вообще не заполнен, просто исчезнут из выборки (так как соединение превратится во внутреннее).

Как найти ссылку на само "Свойство"?

Во всех примерах выше фигурирует переменная СвойствоСсылка. Но как ее получить в коде? Искать по наименованию НайтиПоНаименованию("Длина листа") — плохая практика, так как пользователь может переименовать реквизит в интерфейсе. Рассмотрим два более надежных способа:

  1. По имени для разработчика: В настройках дополнительного реквизита можно указать "Имя для разработчика". Тогда найти его можно так:
    
    СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("ИмяДляРазработчика", "ДлинаЛиста");
    
  2. Через предопределенные наборы: Если вы знаете, к какому набору принадлежит реквизит, можно найти его в табличной части соответствующего элемента справочника НаборыДополнительныхРеквизитовИСведений.

Добавление реквизитов в печатные формы (БП 3.0)

Рассмотрим практический кейс из обсуждения: нужно добавить значение реквизита в печатную форму к названию номенклатуры в Бухгалтерии предприятия 3.0. Для этого нам потребуется подписка на событие или расширение модуля менеджера объекта, где происходит формирование печатной формы (обычно это процедура Печать или СформироватьПечатныеФормы). Для ускорения создания таких доработок можно использовать шаблон внешних подключаемых печатных форм для БСП.

Алгоритм действий будет следующим:

  1. В цикле формирования строк для печати получаем ссылку на текущую номенклатуру или характеристику.
  2. Вызываем функцию УправлениеСвойствами.ЗначениеСвойства() для получения нужного параметра.
  3. Модифицируем переменную, отвечающую за представление товара (наименование).

Пример формирования строки:


ЗначениеДлины = УправлениеСвойствами.ЗначениеСвойства(СтрокаТовара.Характеристика, СвойствоДлина);
Если ЗначениеЗаполнено(ЗначениеДлины) Тогда
    ПредставлениеТовара = Строка(СтрокаТовара.Номенклатура) + " (длина: " + ЗначениеДлины + "м)";
Иначе
    ПредставлениеТовара = Строка(СтрокаТовара.Номенклатура);
КонецЕсли;

Подводя итог, можно сказать, что выбор метода получения дополнительных реквизитов зависит от контекста. Для разовых операций идеально подходят функции БСП, а для массовой обработки данных — запросы к табличным частям с грамотным использованием соединений. Помните о производительности и всегда старайтесь избегать получения объектов целиком там, где достаточно получить одно конкретное значение из таблицы.

← На главную