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