Как в 1С 8.3 открыть форму немодально и получить из нее данные при закрытии

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

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

Метод 1: Использование объекта ОписаниеОповещения

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

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


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

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


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

Чтобы данные попали в РезультатЗакрытия, в самой открытой форме (в нашем примере это ФормаУстановки) при нажатии кнопки «ОК» или «Завершить» необходимо вызвать метод Закрыть(), передав в него данные.


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

Метод 2: Стандартная ОбработкаВыбора

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

Рассмотрим ситуацию, когда нужно выбрать документ реализации с определенным отбором:


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

Для получения результата в вызывающей форме нужно переопределить стандартный обработчик ОбработкаВыбора:


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

Метод 3: Автоматизация через Рефакторинг

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

  1. Откройте конфигуратор и найдите участок кода с модальным вызовом.
  2. Выделите фрагмент кода (например, Выбор = Форма.ОткрытьМодально();).
  3. Нажмите правую кнопку мыши и выберите пункт Рефакторинг, затем — Перенести в немодальный вызов.

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

Метод 4: Современный асинхронный подход (Ждать)

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

Проанализируем пример использования ОткрытьФормуАсинх:


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

Важное примечание: Чтобы использовать этот метод, в свойствах конфигурации должен быть установлен режим совместимости не ниже 8.3.18, а сама процедура должна быть помечена ключевым словом Асинх.

Ключевые моменты при работе с немодальностью

Разберем основные правила, которые помогут избежать ошибок при разработке:

Мы рассмотрели основные способы открытия форм в немодальном режиме. Выбор конкретного метода зависит от версии вашей платформы и архитектурных задач. Использование ОписаниеОповещения является универсальным стандартом, в то время как Ждать — наиболее современным и удобным способом написания чистого кода.

← На главную