При разработке внешних обработок и документов в 1С часто возникает задача: сразу при запуске формы потребовать от пользователя указать обязательный параметр (например, подразделение, склад или участок учета) через стандартную форму выбора. Разберем типичную проблему, возникающую при попытке открыть окно выбора непосредственно в событии ПриОткрытии, выясним ее причину и рассмотрим надежные варианты реализации.
Рассмотрим стандартную попытку вызова окна выбора из обработчика события ПриОткрытии клиентского модуля формы:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ОткрытьФорму("Справочник.УчасткиУчета.ФормаВыбора",, Элементы.УчастокУчета, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
На практике разработчик сталкивается с тем, что форма выбора отображается некорректно: она появляется раньше отрисовки основной формы обработки и не блокирует ее, либо фокус сбивается, позволяя пользователю взаимодействовать с незаполненной основной формой.
Проанализируем жизненный цикл управляемой формы в оконной подсистеме платформы «1С:Предприятие 8.3»:
ПриОткрытии визуальное окно основной формы еще не завершило процесс инициализации и отображения на экране клиента.РежимОткрытияОкнаФормы.БлокироватьОкноВладельца.ОткрытьФормуМодально) запрещено или не рекомендуется, поэтому необходимо использовать асинхронную модель работы окон.Чтобы окно выбора корректно заблокировало основную форму, вызов метода ОткрытьФорму необходимо отложить до момента, когда основная форма будет полностью отрисована на экране. Для этого подключим однократный обработчик ожидания с минимальной задержкой.
Разберем пошаговую реализацию:
ПриОткрытии подключаем однократный таймер через ПодключитьОбработчикОжидания.ОткрытьФорму с указанием владельца и режима блокировки.Посмотрим на пример программного кода:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем однократный обработчик ожидания с задержкой 0.1 секунды
ПодключитьОбработчикОжидания("ОткрытьОкноВыбораУчастка", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ОткрытьОкноВыбораУчастка() Экспорт
// Формируем параметры и оповещение о закрытии формы выбора
Оповещение = Новый ОписаниеОповещения("ПослеВыбораУчастка", ЭтаФорма);
// Открываем форму с блокировкой окна текущей обработки
ОткрытьФорму("Справочник.УчасткиУчета.ФормаВыбора", , Элементы.УчастокУчета, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораУчастка(РезультатВыбора, ДополнительныеПараметры) Экспорт
// Проверяем, заполнил ли пользователь обязательный реквизит
Если Не ЗначениеЗаполнено(Объект.УчастокУчета) Тогда
// Если выбор обязателен, а пользователь закрыл окно крестиком — закрываем форму обработки
ПоказатьПредупреждение(, "Не выбран участок учета! Работа с обработкой невозможна.");
ЭтаФорма.Закрыть();
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее, как платформа ведет себя в зависимости от переданных параметров:
Элементы.УчастокУчета), платформа автоматически подставит выбранное значение в связанный с элементом реквизит и инициирует событие ОбработкаВыбора у этого элемента.ЭтаФорма, результат возвращается в общее событие ОбработкаВыбора формы либо передается в процедуру, заданную через ОписаниеОповещенияОЗакрытии (7-й параметр).РежимОткрытияОкнаФормы.БлокироватьОкноВладельца делает невозможным клики и ввод данных в родительском окне до тех пор, пока подчиненная форма выбора не будет закрыта.Если логика работы обработки полностью зависит от выбранного значения, проанализируем еще один подход: запрашивать значение до открытия самой обработки. В этом случае диалог выбора вызывается в исходном контексте (например, из общей команды или кнопки подсистемы), а выбранное значение передается в параметры формы.
Посмотрим на пример вызова:
&НаКлиенте
Процедура КомандаОткрытьОбработку()
Оповещение = Новый ОписаниеОповещения("ПослеВыбораУчасткаДляОткрытия", ЭтотОбъект);
ОткрытьФорму("Справочник.УчасткиУчета.ФормаВыбора", , ЭтаФорма, , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораУчасткаДляОткрытия(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
ПараметрыФормы = Новый Структура("УчастокУчета", ВыбранноеЗначение);
ОткрытьФорму("Обработка.РабочееМесто.Форма", ПараметрыФормы);
КонецЕсли;
КонецПроцедуры
В самой обработке в обработчике ПриСозданииНаСервере останется только прочитать значение из параметров: Параметры.УчастокУчета и сразу инициализировать форму с готовыми данными без дополнительных всплывающих окон.