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