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