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

Программист 1С v8.3 (Обычные формы)
← На главную

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

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

Метод 1: Передача данных через параметры формы (наиболее гибкий способ)

Проанализируем самый распространенный подход. Управляемая форма при открытии работает не с самим объектом, а с его программной проекцией — ДанныеФормыСтруктура. Чтобы «прокинуть» значения из обычного приложения в управляемое, мы можем использовать структуру параметров. Рассмотрим пошагово, как это реализовать.

Шаг 1. Формирование структуры данных в обычной форме (ОФ). На стороне обычного приложения мы создаем структуру, в которую помещаем все необходимые значения реквизитов нашего объекта.


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

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

ОткрытьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокументаУправляемая", ПараметрыФормы);

Шаг 2. Прием параметров в управляемой форме (УФ). Теперь нам нужно обработать эти данные. Это делается в серверной процедуре ПриСозданииНаСервере модуля управляемой формы.


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

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

Метод 2: Использование механизма временного хранилища (для сложных объектов)

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

Рассмотрим алгоритм действий:

  1. В обычном приложении создаем объект и помещаем его во временное хранилище. Метод ПоместитьВоВременноеХранилище вернет нам уникальный адрес (строку).
  2. Передаем этот адрес в качестве параметра в управляемую форму.
  3. В управляемой форме извлекаем объект из хранилища и конвертируем его в данные формы.

Посмотрим на пример реализации кода в обычной форме:


ДокОбъект = Документы.ЗаказПокупателя.СоздатьДокумент();
// ... заполнение объекта ...

АдресХранилища = ПоместитьВоВременноеХранилище(ДокОбъект, Новый УникальныйИдентификатор);

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("АдресОбъекта", АдресХранилища);

ОткрытьФорму("Документ.ЗаказПокупателя.Форма.ФормаДокумента", ПараметрыФормы);

Теперь реализуем получение данных в управляемой форме. Важным моментом здесь является использование метода ЗначениеВДанныеФормы, который автоматически распределит значения по всем реквизитам формы Объект.


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

Метод 3: Использование «УстановитьСсылкуНового» и прямое открытие

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

Разберем пример кода для обычного приложения:


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

// Генерируем новую ссылку без записи в БД
НоваяСсылка = Документы.ЗаказПокупателя.ПолучитьСсылку(Новый УникальныйИдентификатор);
ДокОбъект.УстановитьСсылкуНового(НоваяСсылка);

// Получаем форму управляемого интерфейса (если она основная) и открываем
// В некоторых случаях это позволяет платформе "подхватить" объект
ДокОбъект.ПолучитьФорму().Открыть();

Важное примечание: Этот метод может работать нестабильно в зависимости от версии платформы и настроек режима совместимости. Платформа 8.3 при вызове управляемой формы часто ожидает именно идентификатор объекта в базе. Если объект не найден, она может инициализировать новую пустую форму. Поэтому использование Метода 2 с временным хранилищем считается более профессиональным и надежным в среде 1С.

Почему нельзя просто передать объект в ОткрытьФорму?

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

Резюмируем:

← На главную