Как программно заполнить реквизиты документа и почему нельзя передавать управляемую форму на сервер

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке внешних обработок и алгоритмов интеграции часто возникает задача: автоматически заполнить реквизиты документа (например, счета учета, договор, срок оплаты) точно так же, как это происходит при интерактивном выборе контрагента или организации пользователем в форме. Начинающие разработчики часто пытаются получить форму программно через ПолучитьФорму() и передать экземпляр формы в серверный модуль или вызвать обработчик события ПриИзменении. Разберем, почему такой подход приводит к ошибкам и как правильно решать подобные задачи в платформе 1С:Предприятие 8.3.

Архитектурные ограничения клиент-серверного взаимодействия

Проанализируем ключевые особенности работы управляемого интерфейса, которые делают передачу формы на сервер невозможной:

  1. Клиентский контекст объекта формы. Объект типа УправляемаяФорма существует исключительно в оперативной памяти клиентского приложения. Он не сериализуется и не может быть передан через границу «клиент-сервер» в качестве параметра серверной процедуры или функции. Попытка выполнить такую передачу приведет к исключению платформы.
  2. Изоляция модуля формы. Экспортные методы формы и контекстные процедуры модуля формы предназначены для обслуживания элементов интерфейса конкретного окна. Вызывать их снаружи из сторонней обработки некорректно.
  3. Разделение данных и интерфейса. В управляемом приложении заполняются реквизиты данных (объект или данные формы), а не сам визуальный интерфейс. Логика автозаполнения счетов, договоров и ставок должна выполняться над данными прикладного объекта.

Способ 1. Программное заполнение и запись объекта на сервере (без открытия формы)

Если задача заключается в том, чтобы программно создать, перезаполнить или обновить существующий документ без интерактивного участия пользователя, нам не требуется получать саму форму. Все манипуляции выполняются с объектом документа на сервере.

Рассмотрим пошаговый пример работы с объектом документа:


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

Такой подход полностью изолирован от интерфейса, работает максимально быстро и гарантирует целостность бизнес-логики конфигурации.

Способ 2. Открытие формы документа с автоматическим заполнением данных

Если необходимо открыть пользователю окно нового или существующего документа с уже подставленными реквизитами и рассчитанными счетами, используем механизм передачи параметров в форму.

Разберем по шагам, как передать структуру значений для заполнения:


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

При таком вызове платформа автоматически передает управление в обработчик ОбработкаЗаполнения модуля объекта документа, а также в процедуру ПриСозданииНаСервере модуля формы, где типовые механизмы корректно инициализируют зависимые счета, договоры и условия оплаты.

Способ 3. Преобразование данных формы на сервере через универсальные методы

В ситуациях, когда форма уже получена программно и требуется модифицировать ее реквизит Объект (имеющий тип ДанныеФормыСтруктура), на сервере используется преобразование структуры формы в реальный объект базы данных и обратно.

Посмотрим на пример работы с методами ДанныеФормыВЗначение и ЗначениеВДанныеФормы:


&НаКлиенте
Процедура ОбработатьФормуПрограммно()
    
    // Получаем форму нужного документа
    мФорма = ПолучитьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокументаУслуги", Новый Структура("Ключ", СсылкаНаДокумент));
    
    // Передаем на сервер данные формы (мФорма.Объект), а не саму форму
    ЗаполнитьДанныеФормыНаСервере(мФорма.Объект);
    
    // Открываем обновленную форму пользователю
    мФорма.Открыть();
    
КонецПроцедуры

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

Важно помнить: передавать на сервер можно только данные (структуры, коллекции, примитивные типы, ссылки или ДанныеФормы). Сама форма (мФорма или ЭтаФорма) всегда остается на клиенте.

← На главную