При разработке простых самописных конфигураций или доработке типовых решений на управляемых формах (интерфейс «Такси») часто возникает задача быстрого подбора номенклатуры в табличную часть документа с помощью сканера штрихкодов. Разберем по шагам архитектуру хранения данных, физические режимы работы сканеров, их ограничения, а также программную реализацию поиска и заполнения строк документа.
Перед написанием логики обработки необходимо определиться со структурой метаданных для хранения штрихкодов. Выделим два основных подхода:
Номенклатура: подходит для предельно простых учетных систем, где каждому элементу номенклатуры строго соответствует только один штрихкод, и учет по характеристикам или упаковкам отсутствует. В этом случае у реквизита Штрихкод (тип Строка) обязательно следует установить свойство Индексировать (или Индексировать с доп. упорядочиванием) для быстрого поиска запросом без полного сканирования таблицы.Штрихкод (тип Строка), а ресурсами — Номенклатура, Характеристика и Упаковка. Регистр автоматически индексирует измерения и позволяет привязывать к одной позиции номенклатуры множество различных кодов (например, разные партии, фасовки или коды производителей).При подключении сканера через USB существует два принципиально разных сценария работы оборудования:
Режим клавиатуры (HID / разрыв клавиатуры): сканер определяется операционной системой как обычная клавиатура и передает считанную последовательность символов в текущий активный элемент интерфейса.
Проанализируем подводные камни этого режима:
Количество или Сумма, считанный штрихкод будет напечатан прямо в это поле.GS (ASCII 29), который драйвер клавиатуры чаще всего отсекает.Режим эмуляции COM-порта (USB-COM / Virtual Serial Port / Native API): сканер переключается сервисным штрихкодом в режим виртуального последовательного порта. При считывании штрихкода данные перехватываются драйвером или компонентой и генерируют в форме событие ВнешнееСобытие независимо от того, где находится курсор.
Если требуется реализовать ввод штрихкода в режиме клавиатуры без подключения «Библиотеки подключаемого оборудования» (БПО), наиболее стабильным решением является использование горячей клавиши и диалога ввода строки. В сканере программируется префикс (например, клавиша F7) и суффикс (Enter). При нажатии горячей клавиши открывается окно ввода, куда сканер сразу же вставляет код и подтверждает ввод.
Рассмотрим пример кода для управляемой формы документа реализации. Создадим команду формы ПоискПоШтрихкоду, назначим ей сочетание клавиш (например, F7) и опишем логику поиска и добавления товара в табличную часть Товары.
На стороне клиента вызываем диалог ввода:
&НаКлиенте
Процедура ПоискПоШтрихкоду(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеВводаШтрихкода", ЭтотОбъект);
ПоказатьВводСтроки(Оповещение, "", НСтр("ru = 'Отсканируйте или введите штрихкод'"));
КонецПроцедуры
&НаКлиенте
Процедура ПослеВводаШтрихкода(Результат, ДополнительныеПараметры) Экспорт
// Если пользователь отменил ввод или строка пустая
Если Не ЗначениеЗаполнено(Результат) Тогда
Возврат;
КонецЕсли;
ШтрихкодОчищенный = СокрЛП(Результат);
// Вызываем серверную функцию для поиска номенклатуры
ДанныеНоменклатуры = НайтиНоменклатуруПоШК(ШтрихкодОчищенный);
Если ДанныеНоменклатуры = Неопределено Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Товар со штрихкодом '") + ШтрихкодОчищенный + НСтр("ru = ' не найден!'"));
Возврат;
КонецЕсли;
// Добавляем или обновляем строку в табличной части
СтрокаТовара = Объект.Товары.Добавить();
СтрокаТовара.Номенклатура = ДанныеНоменклатуры.Ссылка;
СтрокаТовара.Количество = 1;
СтрокаТовара.Цена = ДанныеНоменклатуры.Цена;
СтрокаТовара.Сумма = СтрокаТовара.Количество * СтрокаТовара.Цена;
КонецПроцедуры
Опишем серверную функцию поиска. Выполним запрос к справочнику Номенклатура (или к регистру сведений, если штрихкоды вынесены в отдельную таблицу):
&НаСервереБезКонтекста
Функция НайтиНоменклатуруПоШК(Штрихкод)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| СпрНоменклатура.Ссылка КАК Ссылка,
| СпрНоменклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК СпрНоменклатура
|ГДЕ
| СпрНоменклатура.Штрихкод = &Штрихкод";
Запрос.УстановитьПараметр("Штрихкод", Штрихкод);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
СтруктураРезультата = Новый Структура;
СтруктураРезультата.Вставить("Ссылка", Выборка.Ссылка);
СтруктураРезультата.Вставить("Наименование", Выборка.Наименование);
СтруктураРезультата.Вставить("Цена", 0); // При необходимости получаем актуальную цену из регистра цен
Возврат СтруктураРезультата;
КонецФункции
Если для работы выбран режим эмуляции COM-порта с драйвером подключаемого оборудования, обработка сигнала сканера на управляемой форме строится через предопределенный обработчик ВнешнееСобытие:
&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)
// Проверяем тип события от сканера штрихкода
Если Событие = "BarCodeValue" Или Событие = "Штрихкод" Тогда
СчитанныйШтрихкод = СокрЛП(Данные);
// Передаем штрихкод в процедуру добавления позиции
ОбработатьСчитанныйШтрихкод(СчитанныйШтрихкод);
КонецЕсли;
КонецПроцедуры
Важно помнить о технических особенностях работы внешних компонент:
ПриЗакрытии), иначе порт останется заблокированным для других окон и приложений.