При автоматизации рабочего места кассира или кладовщика часто используется сканер штрихкодов, работающий в режиме эмуляции клавиатуры. При сканировании устройство передает последовательность символов и завершает ввод нажатием клавиши Enter. Разработчики часто сталкиваются с проблемой: после сканирования фокус ввода автоматически перескакивает на следующий элемент формы.
Попытка явного указания текущего элемента в конце обработчика ПриИзменении с помощью кода ЭтаФорма.ТекущийЭлемент = Элементы.Сканирование не дает результата. Проанализируем, почему это происходит, и разберем несколько проверенных способов решения этой задачи.
Выясним механику работы платформы 1С:Предприятие при сканировании. Когда пользователь или сканер нажимает Enter, платформа запускает следующую цепочку событий:
ПриИзменении.ТекущийЭлемент.Enter и переводит фокус на следующий по порядку табуляции элемент формы.Таким образом, переустановка фокуса внутри ПриИзменении отрабатывает корректно, но сразу при выходе из процедуры платформа выполняет стандартный переход, смещая курсор дальше.
Самый простой и штатный способ отменить переход по элементам — перехватить окончание ввода текста и отключить стандартную обработку нажатия Enter.
Разберем по шагам настройку события:
ОкончаниеВводаТекста и сформируем обработчик на клиенте.СтандартнаяОбработка = Ложь.Рассмотри пример кода:
&НаКлиенте
Процедура СканированиеОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Логика обработки считанного штрихкода
ОбработатьШтрихкод(Текст);
// Возвращаем фокус и очищаем поле при необходимости
ТекущийЭлемент = Элементы.Сканирование;
КонецПроцедуры
Установка СтандартнаяОбработка = Ложь блокирует системную реакцию на клавишу Enter, благодаря чему фокус гарантированно остается в исходном поле.
Если логика обработки штрихкода завязана на событие ПриИзменении, можно отложить активацию поля ввода до полного завершения системного перехода платформы.
Для этого в конце процедуры ПриИзменении подключим одноразовый обработчик ожидания с минимальным интервалом:
&НаКлиенте
Процедура СканированиеПриИзменении(Элемент)
// Логика обработки данных
ОбработатьВведенныеДанные();
// Подключаем одноразовый обработчик с задержкой 0.1 секунды
ПодключитьОбработчикОжидания("ВернутьФокусВПолеСканирования", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ВернутьФокусВПолеСканирования()
ТекущийЭлемент = Элементы.Сканирование;
КонецПроцедуры
Важный момент: фокус переносится уже после того, как платформа отработает нажатие Enter, поэтому курсор вернется обратно в нужное поле.
Другой эффективный вариант — создать на форме команду и перехватить нажатие клавиши Enter до того, как платформа начнет обход элементов.
ОбработатьВводKeyEnter).Enter.Так как клавиша Enter будет задействована для выполнения команды формы, системный переход фокуса между элементами запускаться не будет.
Если на форме кроме поля сканирования есть и другие реквизиты (например, таблицы или информационные надписи), можно исключить их из порядка обхода.
Для всех остальных элементов формы установим свойство ПропускатьПриВводе = Истина. Когда платформе некуда переводить фокус после нажатия клавиши Enter, курсор останется в текущем поле сканирования.
Эмуляция клавиатуры часто создает проблемы при высокой скорости работы или фоновом вводе. Наиболее правильным решением с технической точки зрения является интеграция сканера через драйвер 1С:Сканеры штрихкода (NativeApi).
Преимущества данного подхода:
ВнешнееСобытие (даже при работе через USB/клавиатурный порт).ВнешнееСобытие.Посмотрим, как выглядит обработка внешнего события в коде формы:
&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)
Если Источник = "BarCodeScanner" И Событие = "BarCode" Тогда
// Данные содержат прочитанный штрихкод
ОбработатьШтрихкод(СтрЗаменить(Данные, Символы.ПС, ""));
КонецЕсли;
КонецПроцедуры
Для простых форм и быстрых решений рекомендуется использовать событие ОкончаниеВводаТекста с отключением стандартной обработки либо настройку ПропускатьПриВводе для соседних элементов. Для сложных интерфейсов подбора товаров оптимальным решением станет использование специализированного драйвера оборудования с обработкой через ВнешнееСобытие.