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