При работе со сканерами штрихкодов в 1С:Предприятие часто возникает ситуация, когда после считывания кода курсор автоматически перепрыгивает на следующий реквизит формы. Это происходит потому, что большинство сканеров по умолчанию настроены в режиме эмуляции клавиатуры и после передачи цифр штрихкода «нажимают» клавишу Enter. Для оператора, которому нужно сканировать множество товаров подряд, это создает серьезные неудобства: приходится каждый раз возвращать фокус в поле ввода вручную или нажимать дополнительные клавиши. В этой статье мы подробно разберем, как победить стандартное поведение платформы и заставить фокус оставаться там, где он нужен.
Прежде всего, проанализируем ситуацию с точки зрения платформы 1С. Когда сканер работает в режиме эмуляции клавиатуры, система воспринимает его как очень быстрого наборщика текста. После ввода последнего символа сканер посылает управляющий символ CR (Carriage Return), что эквивалентно нажатию клавиши Enter. В управляемых формах 1С нажатие Enter инициирует окончание ввода и, согласно логике обхода элементов, переводит фокус на следующий доступный реквизит. Попытки программно вернуть фокус в событии ПриИзменении часто оказываются безуспешными, так как встроенные механизмы платформы срабатывают уже после выполнения вашего кода. Разберем рабочие способы решения этой задачи.
Это один из самых надежных способов «обмануть» платформу. Суть метода заключается в том, что мы не пытаемся вернуть фокус мгновенно, а дожидаемся, пока платформа завершит свой переход на другой элемент, и только после этого принудительно возвращаем курсор назад. Для этого мы задействуем метод ПодключитьОбработчикОжидания.
Рассмотрим пример реализации. В модуле формы создадим процедуру, которая будет отвечать за возврат фокуса:
&НаКлиенте
Процедура ОбработкаШтрихкода(Элемент)
// Ваша логика поиска товара по штрихкоду
// ...
// Подключаем обработчик ожидания на 0.1 секунды
// Использование однократного вызова (параметр ИспользоватьОдинРаз = Истина)
ПодключитьОбработчикОжидания("УстановитьФокусНаШтрихкод", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьФокусНаШтрихкод()
ТекущийЭлемент = Элементы.ШтрихКод;
КонецПроцедуры
Проанализируем ситуацию: когда срабатывает событие окончания ввода, 1С ставит в очередь выполнение вашей процедуры УстановитьФокусНаШтрихкод. За это время платформа успевает перевести курсор на другой элемент, но через 100 миллисекунд наш код возвращает его обратно. Для пользователя этот процесс выглядит мгновенным и незаметным.
Как отмечалось в обсуждении на форуме, наиболее правильным подходом является корректная настройка самого оборудования. Если сканер работает как клавиатура, мы можем изменить символ-суффикс, который он отправляет в конце сообщения. Вместо стандартного Enter (код 13) можно настроить сканер на использование других комбинаций или вовсе убрать суффикс, если конфигурация позволяет обрабатывать ввод по таймауту.
Однако более эффективным решением будет перевод сканера в режим эмуляции COM-порта (VCOM). Давайте разберем, почему это лучше:
ВнешнееСобытие. Это событие не связано с фокусом на конкретном элементе формы. Курсор может находиться в любом поле или даже быть неактивным — данные все равно будут получены и обработаны.Native API позволяет 1С четко идентифицировать, что данные пришли именно от сканера, а не были введены пользователем вручную.Выясним причину, по которой Enter вызывает переход. В 1С нажатие этой клавиши часто активирует кнопку, у которой установлено свойство КнопкаПоУмолчанию. Мы можем использовать это поведение в своих целях. Разберем по шагам:
КнопкаПоУмолчанию = Истина.
&НаКлиенте
Процедура ОбработатьНажатиеКнопкиПоУмолчанию(Команда)
// Читаем значение из поля ШтрихКод
ШтрихкодДляПоиска = Объект.ШтрихКод;
// Выполняем поиск
НайтиТоварПоШтрихкоду(ШтрихкодДляПоиска);
// Очищаем поле и возвращаем фокус
Объект.ШтрихКод = "";
ТекущийЭлемент = Элементы.ШтрихКод;
КонецПроцедуры
Поскольку кнопка является «дефолтной», нажатие Enter (от сканера) приведет к срабатыванию её кода, а явное указание ТекущийЭлемент в конце процедуры перебьет стандартную логику перехода.
Если на вашей форме много реквизитов и фокус уходит на совершенно ненужные поля (например, на служебные надписи или второстепенные флажки), мы можем ограничить список элементов, участвующих в обходе. Посмотрим на свойство ПропускатьПриПереходе (в конфигураторе оно соответствует TabStop).
Если для всех элементов формы, кроме поля штрихкода, установить это свойство в значение Ложь, то платформе просто некуда будет переводить фокус после нажатия Enter. В некоторых случаях это заставляет курсор оставаться в текущем поле или циклично возвращаться в первое доступное поле формы (которым и будет наш реквизит ШтрихКод).
Важно помнить, что в веб-клиенте работа с фокусом жестко ограничена правилами безопасности браузеров. Если вы разрабатываете решение для браузера, использование ПодключитьОбработчикОжидания становится практически единственным надежным способом управления курсором. Также полезно использовать свойство РежимВыделенияТекста. Если при получении фокуса текст в поле будет автоматически выделяться, оператору не придется очищать поле перед следующим сканированием — новый штрихкод просто заменит старый.
Подводя итог, можно сказать, что идеальное решение зависит от ваших технических возможностей:
1С:Сканеры штрихкода (NativeApi). Это полностью исключит проблему «прыгающего» фокуса.ПодключитьОбработчикОжидания для принудительного возврата фокуса через небольшую паузу.TabStop и скрытые кнопки по умолчанию, чтобы перехватить событие нажатия Enter.Мы рассмотрели основные методы удержания фокуса в поле ввода. Выбор конкретного метода зависит от архитектуры вашего решения, но комбинирование программных методов с правильной настройкой оборудования всегда дает наилучший результат.