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