Как в 1С:Предприятии 8.3 открыть форму и дождаться её закрытия без использования модальных окон?

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

В современных версиях платформы 1С:Предприятие 8.3 использование модальных окон (метод ОткрытьФормуМодально) является нерекомендуемым, а в веб-клиенте и вовсе невозможным. Основная сложность, с которой сталкиваются разработчики при переходе на асинхронную модель, — это необходимость "остановить" выполнение кода до тех пор, пока пользователь не введет данные в открытой форме. В этой статье мы подробно разберем, как правильно реализовать ожидание закрытия формы, передать в неё параметры и получить результат обратно, используя разные механизмы платформы.

Метод 1: Использование Описания Оповещения (классический подход)

Этот метод является базовым для управляемого приложения. Суть его заключается в том, что мы разделяем один алгоритм на две части: до открытия формы и после её закрытия. Рассмотрим ситуацию, когда нам нужно вызвать вспомогательную форму для ввода данных и обработать результат.

Шаг 1: Создание описания оповещения и вызов формы

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


&НаКлиенте
Процедура ВызватьДопФорму(Команда)
    
    // 1. Создаем оповещение, указывая имя процедуры-обработчика и место её расположения (ЭтаФорма)
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияФормы", ЭтаФорма);
    
    // 2. Открываем форму. 
    // Важно: Оповещение передается именно в 7-й параметр метода ОткрытьФорму.
    // РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс имитирует модальность.
    ОткрытьФорму("Обработка.МояОбработка.Форма.ДопФорма", , , , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
    
    // 3. Код после ОткрытьФорму НЕ ДОЛЖЕН содержать логику обработки данных из допформы.
    // Если после вызова формы есть код, выполнение которого нужно пресечь, используем Возврат.
    Возврат; 
    
КонецПроцедуры

Шаг 2: Обработка результата в отдельной процедуре

Когда в дочерней форме будет вызван метод Закрыть(), платформа автоматически выполнит процедуру, имя которой мы указали ранее. Выясним, как она должна выглядеть:


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

Шаг 3: Возврат данных из дочерней формы

Чтобы основная форма получила данные, в коде дочерней формы (например, при нажатии кнопки "ОК") необходимо передать значение в метод Закрыть:


&НаКлиенте
Процедура КомандаОК(Команда)
    СтруктураРезультата = Новый Структура("Значение1", Объект.РеквизитВвода);
    Закрыть(СтруктураРезультата);
КонецПроцедуры

Разбор типичной ошибки: Ошибка преобразования данных XDTO

Часто разработчики пытаются передать объект ОписаниеОповещения внутри структуры параметров (второй аргумент ОткрытьФорму). Это приводит к ошибке: "Ошибка отображения типов: Отсутствует отображение для типа 'ОписаниеОповещения'". Проанализируем причину: параметры формы передаются на сервер для выполнения процедуры ПриСозданииНаСервере. Однако объект ОписаниеОповещения существует только на клиенте и не может быть сериализован для передачи на сервер. Поэтому его нужно передавать только в специально предназначенный 7-й параметр метода ОткрытьФорму.

Метод 2: Современный подход Async/Await (Платформа 8.3.18+)

Если ваша конфигурация работает на версии платформы 8.3.18.1128 и выше, вы можете использовать гораздо более элегантный способ — асинхронные вызовы. Это позволяет писать код "линейно", как в старые добрые времена, но без блокировки потока. Посмотрим на пример использования операторов Асинх и Ждать:


&НаКлиенте Асинх
Процедура ВызватьДопФормуАсинх(Команда)
    
    ПараметрыФормы = Новый Структура;
    
    // Используем метод ОткрытьФормуАсинх с оператором Ждать.
    // Выполнение кода ОСТАНОВИТСЯ на этой строке до момента закрытия формы.
    Результат = Ждать ОткрытьФормуАсинх("Обработка.МояОбработка.Форма.ДопФорма", ПараметрыФормы);
    
    // Код ниже выполнится только ПОСЛЕ закрытия формы
    Если Результат <> Неопределено Тогда
        Сообщить("Результат получен: " + Результат);
    КонецЕсли;
    
КонецПроцедуры

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

Метод 3: Использование встроенного рефакторинга 1С

Если у вас уже есть много старого кода с ОткрытьФормуМодально, и вы хотите быстро его переделать под требования современной платформы, воспользуйтесь встроенным инструментом разработчика:

  1. Найдите в коде вызов ОткрытьФормуМодально.
  2. Нажмите на имени метода правой кнопкой мыши.
  3. Выберите пункт меню Рефакторинг -> Нерекомендуемые серверные вызовы -> Преобразовать вызов.
  4. Платформа предложит создать новую процедуру и автоматически перенесет туда код, следующий за модальным вызовом, создав ОписаниеОповещения самостоятельно.

Важные нюансы блокировки интерфейса

При открытии немодальной формы важно правильно выбрать режим блокировки окна. Рассмотрим два основных варианта в перечислении РежимОткрытияОкнаФормы:

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

← На главную