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