Как программно вернуть фокус в поле ввода управляемой формы 1С после изменения значения?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на управляемых формах 1С программисты часто сталкиваются с задачей циклического ввода данных. Типичный пример — сканирование штрихкодов на складе или в торговом зале. Сценарий выглядит следующим образом: пользователь сканирует код, система обрабатывает данные, очищает поле ввода и должна вернуть курсор (фокус) обратно в это же поле для следующего сканирования. Однако стандартная команда ЭтаФорма.ТекущийЭлемент = Элементы.ИмяЭлемента;, прописанная в обработчике события ПриИзменении, часто не дает ожидаемого результата. В этой статье мы подробно разберем, почему это происходит и как правильно решить проблему.

Анализ проблемы: почему фокус «убегает» из поля

Рассмотрим стандартную ситуацию. У нас есть реквизит формы (не путать с реквизитом объекта, хотя поведение в данном случае схожее) и соответствующее ему поле ввода на форме. Мы пишем код, который должен очистить поле и вернуть в него фокус:


Процедура ШтрихкодПриИзменении(Элемент)
    // Обработка считанного штрихкода
    ДействиеСДанными(ЭтаФорма.Штрихкод);
    
    // Попытка очистить поле и вернуть фокус
    ЭтаФорма.Штрихкод = "";
    ЭтаФорма.ТекущийЭлемент = Элементы.Штрихкод;
КонецПроцедуры

На первый взгляд, код абсолютно логичен. Однако на практике после выполнения этой процедуры фокус все равно переходит на следующий элемент формы в порядке обхода. Почему так происходит? Проанализируем механику работы платформы 1С:Предприятие 8.3.

Когда срабатывает событие ПриИзменении, это означает, что пользователь уже завершил ввод (нажал Enter или перешел в другое поле). Платформа в этот момент уже инициировала процесс смены активного элемента. Ваш программный код выполняется в промежутке между потерей фокуса старым элементом и активацией нового. Установка ТекущийЭлемент внутри обработчика игнорируется, так как после завершения процедуры 1С завершает свой «запланированный» переход к следующему объекту по порядку обхода.

Решение №1: Использование обработчика ожидания

Наиболее надежный и проверенный способ вернуть фокус — это использование механизма ПодключитьОбработчикОжидания. Идея заключается в том, чтобы «отложить» установку фокуса на доли секунды, позволив платформе завершить все стандартные процессы перестроения интерфейса и переходов.

Разберем реализацию этого метода по шагам:

  1. Создадим основную процедуру события ПриИзменении, где вместо прямой установки фокуса вызовем обработчик ожидания.
  2. Создадим отдельную экспортную процедуру на клиенте, которая будет выполнять саму установку фокуса.

Посмотрим на пример кода:


&НаКлиенте
Процедура ШтрихкодПриИзменении(Элемент)
    // Выполняем полезную работу
    ОбработатьВвод(ЭтаФорма.Штрихкод);
    
    // Очищаем данные
    ЭтаФорма.Штрихкод = "";
    
    // Вызываем обработчик ожидания. 
    // Параметры: Имя процедуры, Интервал (0.1 сек), Однократно (Истина)
    ПодключитьОбработчикОжидания("УстановитьФокусНаШтрихкод", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура УстановитьФокусНаШтрихкод() Экспорт
    ЭтаФорма.ТекущийЭлемент = Элементы.Штрихкод;
КонецПроцедуры

Важный нюанс: Интервал 0.1 секунды практически незаметен для пользователя, но его достаточно для того, чтобы стек событий платформы очистился и команда установки фокуса сработала корректно. Параметр Истина (однократно) критически важен, иначе фокус будет принудительно возвращаться в поле каждые 0.1 секунды, блокируя работу с остальной формой.

Решение №2: Настройка свойств порядка обхода

Иногда фокус «улетает» на кнопки или другие декоративные элементы, которые пользователю при сканировании не нужны. Чтобы упростить жизнь платформе и минимизировать программные вмешательства, проанализируем свойства элементов формы.

Выясним, какие элементы можно исключить из процесса навигации. У каждого элемента управления (кнопки, поля ввода, таблицы) есть свойство Пропускать при вводе. Если для всех элементов, кроме целевого поля ввода штрихкода, установить это свойство в значение Истина, платформа физически не сможет перевести фокус никуда, кроме как обратно в ваше поле (или на следующий «разрешенный» элемент).

Этот метод хорошо работает в паре с первым решением, создавая максимально стабильный интерфейс для потокового ввода данных.

Решение №3: Обработка суффикса сканера

Зачастую проблема кроется не в коде 1С, а в настройках оборудования. Физические сканеры штрихкодов обычно имитируют нажатие клавиш клавиатуры. По умолчанию после передачи цифр штрихкода сканер отправляет символ Enter (суффикс возврат каретки) или Tab.

Проанализируем поведение системы:

Если ваша задача — максимально быстрая работа, рекомендуется настроить сканер на работу через Внешнее событие (драйвер устройства ввода). В этом случае фокус вообще не важен: данные попадают в процедуру ВнешнееСобытие формы, обрабатываются программно, а курсор пользователя может оставаться в любом месте. Если же используется эмуляция клавиатуры, то использование ПодключитьОбработчикОжидания остается единственным верным выходом.

Особенности мобильных клиентов

Стоит упомянуть ситуацию с мобильным приложением 1С. На мобильных устройствах установка фокуса через ТекущийЭлемент может не вызвать автоматическое появление экранной клавиатуры. В таких случаях программисты иногда используют «двойной вызов»: сначала устанавливают фокус на вспомогательный элемент, а через микро-паузу (обработчик ожидания) — на нужный. Это заставляет операционную систему мобильного устройства корректно перерисовать интерфейс и активировать ввод.

Резюме по реализации

Подведем итоги. Чтобы гарантированно удерживать фокус в нужном поле ввода на управляемой форме 1С, придерживайтесь следующих правил:

  1. Никогда не пытайтесь установить ТекущийЭлемент напрямую внутри ПриИзменении, если планируется остаться в том же поле.
  2. Всегда используйте однократный обработчик ожидания с минимальной задержкой.
  3. Выносите логику установки фокуса в отдельную экспортную процедуру клиентского модуля.
  4. Проверьте свойства Пропускать при вводе у соседних элементов, чтобы ограничить «пути отхода» для курсора.
  5. Убедитесь, что очистка поля (присваивание пустой строки) происходит до вызова обработчика ожидания, чтобы пользователь сразу видел готовое к работе поле.

Используя эти методы, вы обеспечите плавный и предсказуемый пользовательский интерфейс, который будет работать стабильно вне зависимости от сложности формы и логики обработки данных.

← На главную