Как программно обращаться к дополнительным реквизитам и сведениям

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Переход с редакций 1С 2.0 на 3.0 принес множество изменений в архитектуру данных. Одно из самых значимых — механизм работы с дополнительными реквизитами и сведениями. Если раньше всё хранилось в одном регистре сведений ЗначенияСвойствОбъектов, то теперь логика разделилась: дополнительные реквизиты хранятся в табличных частях самих объектов, а дополнительные сведения — в независимом регистре. В этой статье мы разберем все способы программного обращения к этим данным, от простых запросов до использования профессиональных инструментов Библиотеки Стандартных Подсистем (БСП).

Различие между дополнительными реквизитами и сведениями

Прежде чем писать код, давайте проанализируем, в чем разница между этими двумя механизмами. Это критически важно для выбора метода обращения к ним.

  1. Дополнительные реквизиты — это данные, которые логически являются частью объекта (справочника или документа). Они хранятся в табличной части ДополнительныеРеквизиты. Их удобно использовать, когда значение должно быть доступно непосредственно «внутри» объекта.
  2. Дополнительные сведения — это данные, которые хранятся отдельно от объекта в регистре сведений ДополнительныеСведения. Они используются, когда нужно добавить информацию к объекту без его изменения (например, когда объект уже закрыт для редактирования в прошлом периоде).

Способ 1: Использование модуля БСП «УправлениеСвойствами» (Рекомендуемый)

В современных конфигурациях (БП 3.0, УТ 11, ERP 2.x, ЗУП 3.x) реализована мощная подсистема «Свойства». Самый надежный и простой способ получить значение — использовать функцию общего модуля УправлениеСвойствами. Рассмотрим пример получения значения по строковому имени (заголовку):


// Получаем значение дополнительного реквизита "КПП филиала" для договора
ЗначениеРеквизита = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаДоговор, "КПП филиала");

Если ЗначениеЗаполнено(ЗначениеРеквизита) Тогда
    // Обрабатываем полученное значение
КонецЕсли;

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


// Поиск свойства по наименованию
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Номер реестра");

МассивСвойств = Новый Массив;
МассивСвойств.Добавить(СвойствоСсылка);

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

Способ 2: Обращение к табличной части объекта

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


// Находим ссылку на само свойство
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("КПП филиала");

// Ищем строку в табличной части объекта
СтрокаРеквизита = СсылкаНаОбъект.ДополнительныеРеквизиты.Найти(СвойствоСсылка, "Свойство");

Если СтрокаРеквизита <> Неопределено Тогда
    Значение = СтрокаРеквизита.Значение;
КонецЕсли;

Обратите внимание, что поиск по наименованию через НайтиПоНаименованию — не самый стабильный вариант, так как пользователи могут изменить заголовок в интерфейсе. Рассмотрим более надежный способ поиска по внутреннему имени.

Способ 3: Поиск по внутреннему имени (Имя)

У каждого свойства в Плане Видов Характеристик есть реквизит Имя. Это технический идентификатор, который обычно не меняется пользователями. Проанализируем, как использовать его для более безопасного кода:


// Поиск свойства по уникальному имени, заданному при создании
ИмяСвойства = "ДоговорыКонтрагентов_КППФилиала";
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", ИмяСвойства);

Если Не СвойствоСсылка.Пустая() Тогда
    // Используем найденную ссылку для получения значения
    Значение = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаОбъект, СвойствоСсылка);
КонецЕсли;

Способ 4: Получение данных через запрос

Запросы — самый эффективный метод, если вам нужно получить значения свойств сразу для большого списка объектов (например, в отчете или при обработке данных). Рассмотрим структуру запроса для дополнительных реквизитов:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДоговорыДопРеквизиты.Значение КАК КПП
    |ИЗ
    |	Справочник.ДоговорыКонтрагентов.ДополнительныеРеквизиты КАК ДоговорыДопРеквизиты
    |ГДЕ
    |	ДоговорыДопРеквизиты.Ссылка = &Ссылка
    |	И ДоговорыДопРеквизиты.Свойство.Заголовок = &ИмяСвойства";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДоговор);
Запрос.УстановитьПараметр("ИмяСвойства", "КПП филиала");

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    Сообщить("Найден КПП: " + Выборка.КПП);
КонецЕсли;

Если же мы работаем с дополнительными сведениями, запрос будет адресован к регистру:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДополнительныеСведения.Значение
    |ИЗ
    |	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
    |ГДЕ
    |	ДополнительныеСведения.Объект = &Объект
    |	И ДополнительныеСведения.Свойство = &Свойство";

Запрос.УстановитьПараметр("Объект", СсылкаНаОбъект);
Запрос.УстановитьПараметр("Свойство", СсылкаНаПВХ);
// ... выполнение запроса

Как программно записать значение

Запись данных также рекомендуется выполнять через механизмы БСП, чтобы система корректно обновила кэш и выполнила все необходимые проверки. Выясним, как это реализовать через метод ЗаписатьСвойства.

Для записи нам необходимо подготовить таблицу значений, содержащую колонки Свойство и Значение:


// Подготавливаем структуру для записи
ТаблицаСвойств = Новый ТаблицаЗначений;
ТаблицаСвойств.Колонки.Добавить("Свойство");
ТаблицаСвойств.Колонки.Добавить("Значение");

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.Свойство = СвойствоСсылка; // Ссылка на ПланВидовХарактеристик
НоваяСтрока.Значение = "770101001";   // Новое значение КПП

// Записываем данные (универсально для реквизитов и сведений)
УправлениеСвойствами.ЗаписатьСвойства(ОбъектСсылка, ТаблицаСвойств);

Оптимизация производительности

При формировании печатных форм для большого количества документов (например, массовая печать счетов-фактур) вызов функции УправлениеСвойствами.ЗначениеСвойства в цикле может привести к серьезным задержкам. Проанализируем ситуацию: каждый вызов — это отдельный запрос к базе.

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

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

← На главную