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