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