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