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