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