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