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

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

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

В чем заключается проблема

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ОткрытьФорму("Справочник.УчасткиУчета.ФормаВыбора",, Элементы.УчастокУчета, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры

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

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

Проанализируем жизненный цикл управляемой формы в оконной подсистеме платформы «1С:Предприятие 8.3»:

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

Основное решение: открытие формы через обработчик ожидания

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

Разберем пошаговую реализацию:

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

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


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем однократный обработчик ожидания с задержкой 0.1 секунды
    ПодключитьОбработчикОжидания("ОткрытьОкноВыбораУчастка", 0.1, Истина);
КонецПроцедуры

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

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

Особенности параметров метода ОткрытьФорму

Рассмотрим подробнее, как платформа ведет себя в зависимости от переданных параметров:

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

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

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

Посмотрим на пример вызова:


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

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

В самой обработке в обработчике ПриСозданииНаСервере останется только прочитать значение из параметров: Параметры.УчастокУчета и сразу инициализировать форму с готовыми данными без дополнительных всплывающих окон.

← На главную