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