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