Как использовать аппаратную клавиатуру ТСД для навигации по динамическому списку в мобильном приложении 1С?

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

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

Разберем, почему так происходит и как заставить мобильное приложение 1С реагировать на аппаратные клавиши ТСД для навигации по элементам динамического списка.

Почему навигация не работает "из коробки"

Основная причина кроется в архитектуре мобильной платформы 1С. В отличие от настольной версии, она изначально ориентирована на сенсорное управление (touch-интерфейс). Динамический список на мобильном устройстве обрабатывает касания и свайпы, но не имеет встроенного механизма для преобразования кодов аппаратных клавиш (например, "стрелка вверх" или "стрелка вниз") в команды для смены текущей строки.

Платформа просто не "знает", что нажатие определенной физической кнопки должно приводить к перемещению по списку. Эту логику необходимо реализовать самостоятельно. Задача распадается на два ключевых этапа:

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

Рассмотрим оба этих этапа подробно.

Этап 1: Перехват нажатий с помощью внешней компоненты

Стандартными средствами языка 1С "услышать" нажатие физической клавиши на Android-устройстве невозможно. Для этого необходим мост между операционной системой устройства и средой исполнения 1С. Таким мостом выступает внешняя компонента (ВК).

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

Где взять такую компоненту?

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


&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)

    // Здесь мы будем анализировать пришедшие данные
    // и вызывать процедуру навигации по списку.
    
    // Например, ВК может передавать имя события "KeyPress"
    Если Событие = "KeyPress" Тогда
        
        // В параметре "Данные" может быть код клавиши
        // Например, "ArrowDown" или "ArrowUp". Названия условны 
        // и зависят от конкретной ВК. Их нужно выяснять 
        // из документации к ВК или опытным путем.
        Если Данные = "ArrowDown" Тогда
            ПерейтиНаСледующуюСтрокуСписка();
        ИначеЕсли Данные = "ArrowUp" Тогда
            ПерейтиНаПредыдущуюСтрокуСписка();
        КонецЕсли;
        
    КонецЕсли; 

КонецПроцедуры

Иногда внешние компоненты передают более сложную структуру данных, где нужно анализировать несколько полей. Например, название события (ActionName) и дополнительные параметры (ExtraName), которые могут быть уникальны для каждой модели ТСД.

Этап 2: Программная навигация в динамическом списке

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

Алгоритм действий следующий:

  1. Получить текущую выделенную строку списка (ее идентификатор).
  2. Найти эту строку в коллекции данных формы, чтобы определить ее порядковый номер (индекс).
  3. Вычислить индекс новой строки (текущий индекс +1 для движения вниз, -1 для движения вверх).
  4. Проверить, не выходим ли мы за границы списка (индекс не должен быть меньше 0 или больше либо равен количеству элементов).
  5. Получить элемент данных по новому индексу.
  6. Установить этот элемент как новую текущую строку для элемента формы "Динамический список".

Посмотрим, как это выглядит в коде. Допустим, ваш динамический список на форме называется СписокНоменклатуры.


&НаКлиенте
Процедура ПерейтиНаСледующуюСтрокуСписка()

    // 1. Получаем идентификатор текущей строки
    ТекущийИдентификатор = Элементы.СписокНоменклатуры.ТекущаяСтрока;
    
    // Если ни одна строка не выбрана, выходим
    Если ТекущийИдентификатор = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем коллекцию данных, с которой связан список
    КоллекцияДанных = ДанныеФормыВЗначение(ЭтаФорма.СписокНоменклатуры, Тип("ДанныеФормыКоллекция"));
    
    // 2. Находим элемент данных по идентификатору
    ТекущийЭлементДанных = КоллекцияДанных.НайтиПоИдентификатору(ТекущийИдентификатор);
    
    Если ТекущийЭлементДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Определяем его индекс
    ТекущийИндекс = КоллекцияДанных.Индекс(ТекущийЭлементДанных);
    
    // 3. Вычисляем новый индекс
    НовыйИндекс = ТекущийИндекс + 1;
    
    // 4. Проверяем границы списка
    Если НовыйИндекс >= КоллекцияДанных.Количество() Тогда
        // Мы на последней строке, дальше двигаться некуда
        Возврат;
    КонецЕсли;
    
    // 5. Получаем новый элемент данных
    НовыйЭлементДанных = КоллекцияДанных[НовыйИндекс];
    
    // 6. Устанавливаем новую текущую строку
    Элементы.СписокНоменклатуры.ТекущаяСтрока = НовыйЭлементДанных.ПолучитьИдентификатор();

КонецПроцедуры

&НаКлиенте
Процедура ПерейтиНаПредыдущуюСтрокуСписка()

    ТекущийИдентификатор = Элементы.СписокНоменклатуры.ТекущаяСтрока;
    Если ТекущийИдентификатор = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    КоллекцияДанных = ДанныеФормыВЗначение(ЭтаФорма.СписокНоменклатуры, Тип("ДанныеФормыКоллекция"));
    
    ТекущийЭлементДанных = КоллекцияДанных.НайтиПоИдентификатору(ТекущийИдентификатор);
    Если ТекущийЭлементДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ТекущийИндекс = КоллекцияДанных.Индекс(ТекущийЭлементДанных);
    
    НовыйИндекс = ТекущийИндекс - 1;
    
    // Проверяем, что не ушли "ниже" первой строки
    Если НовыйИндекс < 0 Тогда
        Возврат;
    КонецЕсли;
    
    НовыйЭлементДанных = КоллекцияДанных[НовыйИндекс];
    Элементы.СписокНоменклатуры.ТекущаяСтрока = НовыйЭлементДанных.ПолучитьИдентификатор();

КонецПроцедуры

Важный момент: работа с ДанныеФормыВЗначение и обратно может быть не самой производительной на больших списках. Однако для типичных сценариев на ТСД, где на экране отображается ограниченное количество строк, этот подход вполне рабочий.

Решение сопутствующих проблем

В процессе работы вы можете столкнуться с еще двумя частыми неудобствами.

Как скрыть экранную клавиатуру?

При использовании аппаратной клавиатуры всплывающая экранная клавиатура сильно мешает, перекрывая половину экрана. Решение часто лежит за пределами кода 1С:

Как правильно работать со сканером?

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

В итоге, для полноценной и удобной работы с аппаратной клавиатурой и сканером на ТСД в мобильном приложении 1С необходимо отойти от стандартного функционала и воспользоваться возможностями внешних компонент, дополнив их логикой на встроенном языке 1С.

← На главную