Как правильно открыть и заполнить управляемую форму в тонком клиенте 1С?

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

При переходе с обычных форм на управляемые разработчики часто сталкиваются с трудностями при попытке программно создать документ, заполнить его данными и показать пользователю на клиенте. Попытки вызвать метод Открыть() на стороне сервера или передать объект формы напрямую приводят к ошибкам сериализации XDTO и исключениям платформы.

Разберем детально, почему возникают эти ошибки, как устроена клиент-серверная архитектура управляемого интерфейса и какие подходы являются наиболее правильными и надежными.

Анализ типичных ошибок при открытии формы

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

  1. Попытка открыть форму на сервере. В управляемом приложении сервер отвечает исключительно за обработку данных и бизнес-логику. Визуальные интерфейсные методы, такие как Открыть(), доступны только в контексте &НаКлиенте. Сервер не имеет графического окружения.
  2. Недопустимая передача контекста и объектов базы. Типы ДокументОбъект.* и СправочникОбъект.* не могут передаваться на тонкий клиент. При попытке передать неинициализированную структуру данных формы через границу «клиент-сервер» возникает ошибка: «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка преобразования данных XDTO».

Способ 1. Использование встроенного механизма заполнения на основании (Рекомендуемый)

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

Посмотрим на пример клиентского кода:


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

Выясним, как работает этот механизм изнутри:

  1. Платформа самостоятельно выполняет серверный вызов и создает экземпляр документа.
  2. Автоматически вызывается серверная процедура ОбработкаЗаполнения в модуле создаваемого документа, куда в качестве параметра передается ссылка из структуры Основание.
  3. Форма документа инициализируется уже заполненными данными и открывается на тонком клиенте без дополнительных манипуляций со стороны разработчика.

Способ 2. Заполнение произвольных реквизитов через «ЗначенияЗаполнения»

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

Рассмотрим практический пример реализации:


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

В этом случае платформа передает указанную структуру в событие ОбработкаЗаполнения модуля объекта, и все реквизиты с совпадающими именами подставляются автоматически.

Способ 3. Передача пользовательских параметров и обработка в «ПриСозданииНаСервере»

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

Посмотрим, как организовать передачу данных по шагам:

  1. На стороне вызывающей формы формируем структуру с произвольными параметрами и открываем целевую форму:

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("КодКлиента") Тогда
        НайденныйКонтрагент = Справочники.Контрагенты.НайтиПоКоду(Параметры.КодКлиента);
        Если ЗначениеЗаполнено(НайденныйКонтрагент) Тогда
            Объект.Контрагент = НайденныйКонтрагент;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Способ 4. Программная трансформация данных через «ДанныеФормыВЗначение»

Рассмотрим случай, когда требуется программно получить форму, преобразовать ее реквизиты в полноценный прикладной объект на сервере, выполнить над ним действия и вернуть обратно в контекст формы. Такой подход используется редко, но полезен при динамической модификации сложных наборов данных.

Разберем пример с корректным преобразованием типов:


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

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

Сводные рекомендации

Чтобы избежать ошибок при открытии и заполнении управляемых форм, придерживайтесь следующих правил:

  1. Всегда выполняйте открытие формы исключительно на клиенте с помощью функции ОткрытьФорму().
  2. Для указания стандартного окна документа используйте системное имя формы "Документ.ИмяДокумента.ФормаОбъекта" вместо жестко заданных путей к конкретным общим формам.
  3. Для ввода на основании используйте параметр Основание, а для начальной подстановки полей — структуру ЗначенияЗаполнения.
  4. Не передавайте объекты баз данных (ДокументОбъект) между клиентом и сервером — передавайте только ссылки, примитивные типы и структуры.
← На главную