К статье
Практический материал

Разработка и Конфигурация · 12 мин

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

Как программно обратиться к дополнительным реквизитам и сведениям в 1С: чтение и запись значений, поиск по имени, работа через табличную часть и запросы.

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

Механизм реализован в библиотеке стандартных подсистем (БСП) и работает в типовых конфигурациях: «Управление торговлей», «ERP», «Бухгалтерия предприятия», «Зарплата и управление персоналом» и других. Сами свойства хранятся в плане видов характеристик «ДополнительныеРеквизитыИСведения», а их значения — либо в табличной части объекта, либо в регистре сведений.

Ниже разобраны рабочие способы чтения и записи дополнительных реквизитов: через табличную часть объекта, через запрос, через функции БСП, а также особенности работы с дополнительными сведениями и типичные ошибки, которые приводят к пустым значениям или дублям строк.

Где физически хранятся дополнительные реквизиты и сведения

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

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

Узнать, чем является конкретное свойство — реквизитом или сведением, — можно в интерфейсе: «Администрирование → Общие настройки → Дополнительные реквизиты и сведения». Там свойства разбиты на две группы. Программно это тоже различимо: если у объекта есть табличная часть «ДополнительныеРеквизиты» и в ней есть строка с нужным свойством — это реквизит.

Как найти ссылку на свойство

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

// Поиск свойства по наименованию

Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения

.НайтиПоНаименованию("Цвет товара", Истина);

Если Свойство.Пустая() Тогда

// Свойство не создано — обработать ситуацию

КонецЕсли;

Искать по наименованию следует с параметром «Точное соответствие» равным Истина, иначе при частичном совпадении можно получить чужое свойство. Более надёжный вариант — искать по реквизиту «Имя» через запрос, поскольку имя не редактируется пользователем в произвольной форме и не содержит проблем с раскладкой.

Чтение значения дополнительного реквизита из объекта

Когда объект уже получен (через ПолучитьОбъект() или в модуле объекта), значение читается перебором или поиском строки табличной части:

// Чтение значения дополнительного реквизита

ПараметрыОтбора = Новый Структура("Свойство", Свойство);

Строки = Объект.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);

Если Строки.Количество() > 0 Тогда

ЗначениеЦвета = Строки[0].Значение;

Иначе

// Реквизит у объекта не заполнен

КонецЕсли;

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

Если нужно прочитать значения у множества объектов, перебор с ПолучитьОбъект() для каждой ссылки будет медленным. В этом случае используйте запрос к табличной части сразу для списка ссылок — об этом ниже.

Запись значения дополнительного реквизита

Запись выполняется симметрично: ищем строку, а если её нет — добавляем новую. После изменения объект нужно записать.

// Запись значения дополнительного реквизита

ОбъектТовара = СсылкаНаТовар.ПолучитьОбъект();

ПараметрыОтбора = Новый Структура("Свойство", Свойство);

Строки = ОбъектТовара.ДополнительныеРеквизиты.НайтиСтроки(ПараметрыОтбора);

Если Строки.Количество() > 0 Тогда

СтрокаСвойства = Строки[0];

Иначе

СтрокаСвойства = ОбъектТовара.ДополнительныеРеквизиты.Добавить();

СтрокаСвойства.Свойство = Свойство;

КонецЕсли;

СтрокаСвойства.Значение = НовоеЗначение;

ОбъектТовара.Записать();

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

Типичные ошибки
01
Добавление строки без поиска существующей — в табличной части появляются дубли одного свойства, и в интерфейсе видно не то значение, которое записала обработка.
02
Запись значения несовместимого типа — при записи объекта возникает ошибка преобразования или значение молча обрезается.
03
Изменение объекта без Записать() — значение меняется только в памяти и теряется.
04
Обращение к Объект.ДополнительныеРеквизиты у ссылки — у ссылки нет табличной части, сначала нужен ПолучитьОбъект() или запрос.

Работа с дополнительными сведениями через регистр

Дополнительные сведения читаются и пишутся без получения объекта. Для чтения удобен запрос:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДопСведения.Значение

|ИЗ

| РегистрСведений.ДополнительныеСведения КАК ДопСведения

|ГДЕ

| ДопСведения.Объект = &Объект

| И ДопСведения.Свойство = &Свойство";

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

Запрос.УстановитьПараметр("Свойство", Свойство);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

ЗначениеСведения = Выборка.Значение;

КонецЕсли;

Для записи используется менеджер записи регистра:

МенеджерЗаписи = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Объект = СсылкаНаТовар;

МенеджерЗаписи.Свойство = Свойство;

МенеджерЗаписи.Значение = НовоеЗначение;

МенеджерЗаписи.Записать(Истина);

Чтобы удалить сведение, вызовите Прочитать() у менеджера записи, проверьте Выбран() и затем вызовите Удалить(). Это безопаснее, чем запись пустого значения: пустая строка в регистре остаётся и может мешать отборам.

Массовое чтение через запрос к табличной части

Для отчётов и обработок по списку объектов обращайтесь к табличной части напрямую в запросе. Имя таблицы формируется как «Справочник.Номенклатура.ДополнительныеРеквизиты»:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДопРеквизиты.Ссылка КАК Товар,

| ДопРеквизиты.Значение КАК Цвет

|ИЗ

| Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДопРеквизиты

|ГДЕ

| ДопРеквизиты.Свойство = &Свойство

| И ДопРеквизиты.Ссылка В (&СписокТоваров)";

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

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

Использование функций БСП

В типовых конфигурациях есть готовые процедуры модуля «УправлениеСвойствами» (в старых версиях — «УправлениеСвойствамиСлужебный», «СвойстваПереопределяемый»). Они инкапсулируют описанную логику: получение значений свойств объекта, запись значений, работу с наборами. Использование этих функций снижает объём собственного кода и упрощает обновление конфигурации.

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

Проверка результата и частые проблемы

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

Если значение не сохраняется, проверьте: входит ли свойство в набор дополнительных реквизитов данного вида объектов, есть ли у пользователя права на запись объекта, не срабатывает ли обработчик «ПередЗаписью», очищающий табличную часть. Для дополнительных сведений дополнительно проверьте права на регистр сведений.

Контрольные точки

Как проверить результат

Отображение в карточке объекта
Норма

Значение видно в группе дополнительных реквизитов

Тревожный признак

Поле пустое или свойства нет в списке — свойство не в наборе вида объектов

Контрольный запрос по табличной части
Норма

Запрос возвращает записанное значение

Тревожный признак

Пусто — проверьте ссылку на свойство и факт записи объекта

Количество строк по свойству у объекта
Норма

Одна строка на свойство

Тревожный признак

Несколько строк — дубли от некорректной записи

Итог

Что важно запомнить

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

Частые вопросы

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

Нет. Дополнительные реквизиты не являются полями объекта в метаданных, поэтому конструкция вида Объект.Цвет работать не будет. Обращение идёт только через табличную часть «ДополнительныеРеквизиты» с поиском строки по свойству либо через запрос.

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

Проверьте наличие строки с этим свойством в табличной части «ДополнительныеРеквизиты» объекта: если строка есть или может быть добавлена — это реквизит. Также можно открыть настройки в разделе «Администрирование → Дополнительные реквизиты и сведения», где свойства разделены на две группы.

Почему запрос к табличной части не возвращает значение, хотя в карточке оно есть?

Чаще всего причина в несовпадении ссылки на свойство: в базе существует несколько свойств с одинаковым наименованием, и вы передаёте в параметр не ту ссылку. Сравните ссылку свойства из строки табличной части с той, которую находит ваш поиск. Реже причина — устаревший кэш: перезапустите сеанс.

Как записать значение, если тип свойства — список дополнительных значений?

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

Можно ли заполнить дополнительное сведение, не изменяя проведённый документ?

Да, это одно из главных преимуществ сведений. Значение записывается менеджером записи регистра «ДополнительныеСведения» напрямую, объект при этом не изменяется и не перепроводится. Достаточно прав на запись регистра.

Чем опасно добавление строки в табличную часть без предварительного поиска?

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