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