В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартные механизмы ввода текста требуют расширения. Один из самых популярных способов — использование события ОкончаниеВводаТекста для подбора значений из динамически сформированного списка. Однако пользователи версий 8.3.19 и 8.3.20 массово столкнулись с неприятным поведением системы: список выбора появляется на долю секунды и тут же исчезает, не давая возможности выбрать нужный элемент. В этой статье мы подробно разберем, почему это происходит и как обойти данное ограничение платформы.
Давайте проанализируем стандартный код, который обычно вызывает это затруднение. Программист переопределяет стандартную обработку завершения ввода, чтобы предложить пользователю свои варианты:
&НаКлиенте
Процедура РеквизитОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Список = Новый СписокЗначений;
Список.Добавить("Вариант 1");
Список.Добавить("Вариант 2");
Список.Добавить("Вариант 3");
ДанныеВыбора = Список;
КонецПроцедуры
На более старых версиях платформы (например, 8.3.18) этот код работает безупречно. Но в ветках 8.3.19 и 8.3.20 разработчики платформы внесли изменения в механизмы управления фокусом и отрисовки всплывающих окон. В результате возникла ошибка: когда параметр СтандартнаяОбработка устанавливается в значение Ложь, внутренние процессы платформы по завершении редактирования поля (потери фокуса) срабатывают некорректно. Система посылает сигнал на закрытие всех дочерних окон ввода, включая только что сформированный список ДанныеВыбора.
Проанализируем ситуацию: это официально зафиксированный баг платформы (например, ошибка №10234033). Он проявляется именно при использовании клавиш Enter или Tab. Если же завершение ввода происходит при клике мышкой в другое поле, список может отработать нормально, что подтверждает проблему в обработке клавиатурных событий клиентского приложения.
Первым делом рассмотрим самый правильный с точки зрения системного администрирования путь. Поскольку проблема является платформенной, фирма «1С» выпустила исправления в последующих релизах. Если у вас есть возможность обновить платформу, ориентируйтесь на следующие версии:
Если же ваша конфигурация (например, свежая БП 3.0) жестко требует конкретную версию платформы, которая входит в «проблемную» зону, или вы ограничены регламентами предприятия, перейдем к рассмотрению программных обходных путей.
Современный интерфейс «Такси» предполагает более интерактивное взаимодействие с пользователем. Вместо того чтобы ждать нажатия Enter, мы можем предлагать варианты сразу в процессе набора текста. Давайте разберем, как перенести логику в событие АвтоПодбор. Это событие работает более стабильно, так как оно не связано с моментом «завершения» редактирования поля и потерей фокуса.
Рассмотрим пример реализации:
&НаКлиенте
Процедура РеквизитАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
Если СтрДлина(Текст) < 3 Тогда
Возврат;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Список = Новый СписокЗначений;
// Здесь может быть запрос к серверу для получения данных
Список.Добавить("Результат на основе " + Текст);
ДанныеВыбора = Список;
КонецПроцедуры
Использование АвтоПодбор позволяет избежать конфликта при закрытии поля, так как список выбора открывается в режиме «предложения», а не «финализации» ввода. Для пользователя это выглядит даже удобнее и современнее.
Если логика вашей задачи требует работы именно после полного ввода текста (по нажатию Enter), проанализируем вариант с небольшой задержкой. Суть метода заключается в том, чтобы дать платформе завершить все свои «глючные» внутренние процессы по закрытию фокуса и только после этого принудительно показать список выбора.
Посмотрим на алгоритм реализации по шагам:
ОкончаниеВводаТекста мы сохраняем введенный текст в переменную модуля формы.СтандартнаяОбработка = Ложь.ВыбратьИзСписка.Пример кода для реализации этого метода:
&НаКлиенте
Перем СохраненныйТекст;
&НаКлиенте
Процедура РеквизитОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
СохраненныйТекст = Текст;
ПодключитьОбработчикОжидания("ПоказатьСписокВыбораПослеПаузы", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьСписокВыбораПослеПаузы()
Список = Новый СписокЗначений;
// Формируем список на основании СохраненныйТекст
Список.Добавить("Значение 1");
ЭлементФормы = Элементы.Реквизит;
ВыбранныйЭлемент = ВыбратьИзСписка(Список, ЭлементФормы);
Если ВыбранныйЭлемент <> Неопределено Тогда
Объект.Реквизит = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецПроцедуры
Важный нюанс: метод ВыбратьИзСписка в данном контексте сработает надежнее, чем попытка заполнить параметр ДанныеВыбора, так как мы явно управляем процессом отображения окна после того, как основной поток событий платформы «успокоился».
Иногда проблему удается решить изменением настроек самого элемента управления на форме. Разберем, какие свойства могут повлиять на поведение списка:
Не обновлять (или Ложь программно). Хотя в некоторых случаях это не помогает (как отмечали участники форума), в сочетании с другими методами это может стабилизировать фокус.Да, поле превращается в подобие выпадающего списка. Это кардинально меняет поведение события ОкончаниеВводаТекста, но если вам заранее известен набор значений, этот вариант будет самым стабильным.Мы проанализировали ситуацию с исчезающим списком выбора и выяснили, что основной причиной является критическая ошибка в определенных релизах платформы 1С 8.3.19 и 8.3.20.
Для решения задачи мы рекомендуем придерживаться следующей последовательности действий:
АвтоПодбор, что является более правильным с точки зрения UX/UI управляемого интерфейса.ПодключитьОбработчикОжидания для искусственной задержки открытия списка, чтобы обойти некорректную обработку фокуса платформой.Применяя эти подходы, вы сможете обеспечить стабильную работу ваших внешних обработок и конфигураций даже на проблемных версиях технологической платформы.