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