При разработке интерфейсов на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с существенным ограничением: стандартное событие ПриИзменении для текстового поля срабатывает только после того, как пользователь нажмет клавишу Enter или переведет фокус на другой элемент с помощью мыши. Это создает неудобства при автоматизации ввода данных, например, когда необходимо перевести курсор из одного поля в другое сразу после ввода 10-го символа штрихкода.
Рассмотрим подробнее, почему штатные средства ОбработкаОжидания и АктивныйЭлемент не решают задачу в реальном времени, и разберем работающие альтернативные методы, позволяющие обойти это ограничение.
Проанализируем самый простой способ, который не требует глубокого погружения в программный код. Большинство современных сканеров штрихкодов могут работать в режиме «разрыва клавиатуры» (HID). В этом режиме сканер имитирует быстрый ввод символов пользователем.
Для реализации автоматического перехода мы можем запрограммировать сканер на добавление управляющего символа после каждого считанного штрихкода:
Tab, фокус автоматически переместится на следующее поле ввода, определенное в порядке обхода формы.Enter, платформа 1С воспримет это как окончание ввода в текущем поле. В модуле формы в процедуре, связанной с полем, мы сможем программно вызвать АктивизироватьОбъект("Поле2").Если нам необходимо программно контролировать каждое нажатие клавиши, стандартных средств 1С 7.7 будет недостаточно. В этом случае воспользуемся популярной внешней компонентой FormEx. Она расширяет событийную модель формы.
Разберем алгоритм работы с событием ПослеНажатияКлавиши. Эта процедура позволяет перехватывать ввод до того, как данные будут окончательно зафиксированы в поле. Пример логики может выглядеть следующим образом:
Процедура ПослеНажатияКлавиши(КодКлавиши, Альт, Шифт, Контрол, Символ, Флаг)
// Проверяем, что фокус находится на нужном нам поле
Если СокрЛП(Форма.АктивныйЭлемент()) = "Поле1" Тогда
// Проверяем длину введенного текста в объекте
// Внимание: для получения текущего текста в момент ввода
// могут потребоваться дополнительные методы FormEx
Если СтрДлина(Поле1) >= 10 Тогда
АктивизироватьОбъект("Поле2");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Использование этого метода позволяет пользователю даже не замечать процесса переключения — управление передается мгновенно при достижении лимита символов.
Выясним причину, по которой работа через «разрыв клавиатуры» (HID) считается менее надежной для профессиональных решений. При использовании HID-режима данные попадают в активное поле ввода, и если в этот момент фокус случайно окажется в другом месте (например, в поиске), данные будут испорчены.
Рекомендуется перевести сканер в режим VCP (Virtual COM Port). В этом случае 1С будет получать данные через процедуру ОбработкаВнешнегоСобытия. Это полностью снимает проблему фокуса:
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
Если (Источник = "Scanner") И (Событие = "BarCodeValue") Тогда
Штрихкод = СокрЛП(Данные);
// Распределяем данные программно
Если СтрДлина(Поле1) < 10 Тогда
Поле1 = Штрихкод;
АктивизироватьОбъект("Поле2");
Иначе
Поле2 = Штрихкод;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Существует специфический «хак» для 1С 7.7, который заставляет платформу принудительно обновить состояние переменных формы и прочитать данные из буфера ввода. Рассмотрим, как это работает через механизм СтатусВозврата(0).
Суть заключается в вызове команды закрытия формы, которая прерывается в предопределенной процедуре. Это заставляет систему «сбросить» введенные в поле символы в связанную переменную Поле1. Однако данный метод может вызывать мерцание экрана и считается нестабильным, поэтому использовать его стоит только при невозможности подключения внешних компонент.
Посмотрим на ситуацию с точки зрения расширения графического интерфейса. Мы можем разместить на форме 1С объект TextBox из библиотеки Microsoft Forms 2.0 (FM20.DLL).
В отличие от родных полей 1С 7.7, у объектов ActiveX есть полноценное событие Change, которое срабатывает на каждый введенный символ. Проанализируем примерный код обработки такого события:
// Предположим, TextBox1 — это наш ActiveX объект на форме
Процедура OnChangeTextBox1()
Если СтрДлина(Форма.TextBox1.Text) = 10 Тогда
// Выполняем переход на следующее поле
АктивизироватьОбъект("Поле2");
КонецЕсли;
КонецПроцедуры
Этот способ обеспечивает максимально «чистое» решение с точки зрения интерфейса, так как не требует перехвата глобальных нажатий клавиш всей системы.
Мы рассмотрели несколько подходов к решению задачи автоматического перевода фокуса. Наиболее надежным для складских и торговых задач является использование сканера в режиме COM-порта. Если же необходимо оставить работу через имитацию клавиатуры, оптимальным выбором станет использование компоненты FormEx или настройка суффиксов самого оборудования. Выбор конкретного метода зависит от возможности установки внешних библиотек в вашей системе и модели используемого оборудования.