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