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

Рис. 3.13. Кнопки стандартных команд в командной панели
После закрытия формы ПараметрыЗаполнения одной из этих стандартных команд будет выполнена процедура обработки оповещения ЗадатьПараметрыЗаполненияЗавершение(). В параметре Результат этой процедуры будет содержаться код возврата диалога, значения которого описаны в системном перечислении КодВозвратаДиалога.
Расположим процедуру обработки оповещения в модуле формы исходной обработки и проанализируем возвращаемый результат, выведя в форму обработки сообщение, соответствующее нажатой кнопке в форме ПараметрыЗаполнения (листинг 3.15).
Листинг 3.15. Обработчик оповещения «ЗадатьПараметрыЗаполненияЗавершение»
&НаКлиенте
Процедура ЗадатьПараметрыЗаполненияЗавершение(Результат, ДополнительныеПараметры) Экспорт
Сообщение = Новый СообщениеПользователю;
Если Результат = КодВозвратаДиалога.ОК Тогда
Сообщение.Текст = "В форме нажата стандартная кнопка ОК";
ИначеЕсли Результат = КодВозвратаДиалога.Пропустить Тогда
Сообщение.Текст = "В форме нажата стандартная кнопка Пропустить";
ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда
Сообщение.Текст = "В форме нажата стандартная кнопка Отмена";
Иначе
Сообщение.Текст = "Обработка этой команды в форме не предусмотрена";
КонецЕсли;
Сообщение.Сообщить();
КонецПроцедуры
Обратите внимание, что процедура обработки оповещения должна быть объявлена как экспортная, с использованием ключевого слова Экспорт.
Теперь рассмотрим вторую возможность – возврат произвольного значения из блокирующей формы.
Для этого создадим еще одну форму обработки – ДобавлениеТекста. В ней создадим строковый реквизит (Текст) и поле для его редактирования. Добавим команду ЗакончитьВводТекста, по которой будем возвращать введенный пользователем текст (рис. 3.14).

Рис. 3.14. Команда «ЗакончитьВводТекста» в форме «ДобавлениеТекста»
Обработчик команды ЗакончитьВводТекста будет выглядеть совсем просто (листинг 3.16).
Листинг 3.16. Обработчик команды «ЗакончитьВводТекста»
Закрыть(Текст);
А в основной форме обработки добавим команду ДобавитьТекст, которая будет открывать форму ДобавлениеТекста в блокирующем режиме (листинг 3.17).
Листинг 3.17. Обработчик команды «ДобавитьТекст»
ОписаниеОповещения = Новый ОписаниеОповещения("ДобавитьТекстЗавершение", ЭтотОбъект);
ОткрытьФорму("Обработка.ЗаполнениеДанных.Форма.ДобавлениеТекста", , , , , , ОписаниеОповещения, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
Обратите внимание, что в данном случае блокирующее окно открыто в режиме блокирования окна владельца.
После закрытия формы ДобавлениеТекста будет выполнена процедура обработки оповещения ДобавитьТекстЗавершение(). В параметре РезультатЗакрытия этой процедуры будет содержаться текст, введенный пользователем в блокирующей форме.
Расположим процедуру обработки оповещения в модуле формы исходной обработки и выведем этот текст в сообщение (листинг 3.18).
Листинг 3.18. Обработчик команды «ДобавитьТекстЗавершение»
&НаКлиенте
Процедура ДобавитьТекстЗавершение(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "В форме введен текст: " + РезультатЗакрытия;
Сообщение.Сообщить();
КонецПроцедуры
К примерам реализации отказа от модальности мы еще вернемся (метод ), (метод ), (метод ), (метод в обработчике события).