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