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

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

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

Разберем причины такого поведения платформы 1С:Предприятие и рассмотрим надежные способы решения этой задачи.

Почему не работает установка свойства ТекущийЭлемент в событии ПриИзменении

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

Даже если внутри процедуры мы принудительно переназначим ТекущийЭлемент или попробуем переключить фокус на соседнее поле и обратно, завершающая логика платформы всё равно переопределит наш выбор и сместит курсор дальше. Чтобы удержать фокус, необходимо вмешаться в процесс на следующем такте работы клиентского интерфейса либо перехватить ввод на более раннем этапе.

Способ 1. Отложенная установка фокуса через разовый обработчик ожидания

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

Рассмотрим реализацию данного подхода по шагам:

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

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


&НаКлиенте
Процедура ЮрАдресКонтрагентаПриИзменении(Элемент)
    
    // Выполняем серверную обработку введенных данных при необходимости
    ЮрАдресКонтрагентаПриИзмененииНаСервере();
    
    // Запускаем разовый обработчик для возврата фокуса
    ПодключитьОбработчикОжидания("УстановитьФокусНаАдрес", 0.1, Истина);
    
КонецПроцедуры

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

Важный момент: интервал менее 1 секунды платформой поддерживается только при условии, что параметр Однократно установлен в значение Истина. При таком вызове фокус возвращается мгновенно и незаметно для пользователя, не создавая постоянной циклической нагрузки на клиентское приложение.

Способ 2. Настройка свойства формы ПоведениеКлавишиEnter

Если смещение фокуса происходит именно по нажатию клавиши Enter при вводе данных в поле, можно скорректировать поведение самой формы.

  1. Открываем свойства управляемой формы в конфигураторе.
  2. Находим параметр ПоведениеКлавишиEnter.
  3. Переключаем его со значения Переход на Кнопка по умолчанию.

После этой настройки нажатие Enter не будет инициировать автоматический переход к следующему элементу по порядку обхода, и присвоение ТекущийЭлемент = Элементы.ИмяПоля в обработчике ПриИзменении сработает корректно:


&НаКлиенте
Процедура ЛистПриИзменении(Элемент)
    ТекущийЭлемент = Элементы.Лист;
КонецПроцедуры

Способ 3. Перехват выбора через событие ОбработкаВыбора

Если задача заключается в том, чтобы выбирать фрагменты текста из выпадающего списка и сразу же дописывать строку дальше, правильнее обрабатывать не ПриИзменении, а событие ОбработкаВыбора самого элемента формы.

Разберем программный код:


&НаКлиенте
Процедура ЮрАдресКонтрагентаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    
    // Отменяем стандартное поведение платформы
    СтандартнаяОбработка = Ложь;
    
    // Дополняем текущий реквизит выбранным значением
    Объект.ЮрАдресКонтрагента = Строка(Объект.ЮрАдресКонтрагента) + " " + Строка(ВыбранноеЗначение);
    
    // Обновляем отображение текста в поле ввода без потери позиции редактирования
    Элемент.ОбновитьТекстРедактирования();
    
    // Удерживаем фокус на элементе
    ТекущийЭлемент = Элемент;
    
КонецПроцедуры

Установка СтандартнаяОбработка = Ложь предотвращает стандартный сход с элемента управления, а метод ОбновитьТекстРедактирования() синхронизирует отображаемый текст с данными реквизита объекта.

Способ 4. Использование событий автоподбора и окончания ввода текста

В сценариях живого ввода текста без прерывания набора можно задействовать специализированные события поля ввода:

  1. АвтоПодбор / АвтоПодборТекста: срабатывает при наборе символов или открытии списка подсказок. Позволяет динамически формировать варианты подстановки без сброса курсора.
  2. ОкончаниеВводаТекста: перехватывает ввод до момента окончательной фиксации значения. Установив СтандартнаяОбработка = Ложь, можно программно обработать строку. Следует учитывать, что внутри этого события нельзя выполнять синхронные контекстные серверные вызовы (директива &НаСервере), так как они приводят к принудительному завершению редактирования и потере активности поля.
← На главную