На рабочих местах кассиров или на складах часто возникает практическая необходимость использовать два сканера штрихкодов на одном персональном компьютере. Например, один сканер может быть стационарным (многоплоскостным) для быстрого считывания этикеток с мелких товаров, а второй — беспроводным или ручной моделью на длинном кабеле для работы с крупногабаритным грузом, который тяжело поднести к кассовому узлу. Однако при стандартном подключении обоих устройств в классической конфигурации 1С:Управление торговлей 10.3 (а также в аналогичных решениях на обычных формах, таких как 1С:Управление производственным предприятием 1.3 или 1С:Розница 1.0) пользователи сталкиваются с неприятным багом: при сканировании любого штрихкода количество товара в открытом документе увеличивается сразу на две единицы.
В этой статье мы подробно проанализируем архитектурные особенности обработки сигналов торгового оборудования в платформе 1С, выясним техническую причину возникновения этого сбоя и разберем по шагам несколько эффективных способов решения проблемы.
Давайте разберем по шагам, как именно программа 1С реагирует на считывание штрихкода физическим сканером. В момент успешного распознавания штрихкода внешняя компонента (драйвер оборудования) посылает сигнал операционной системе, который перехватывается платформой 1С. В этот момент в системе вызывается предопределенная процедура ВнешнееСобытие(Источник, Событие, Данные).
В данную процедуру передаются три основных параметра:
"BarCodeScan" или "InputDevice")."BarCodeValue").В стандартном программном коде 1С заложен универсальный механизм обработки. При получении внешнего события система обращается к механизмам общего модуля РаботаСТорговымОборудованием (или обработке ТОСервер в зависимости от релиза конфигурации). Внутри этого модуля запускается цикл обхода всех подключенных и активных на данном рабочем месте устройств типа «Сканер штрихкода».
Поскольку в настройках торгового оборудования у вас зарегистрировано два сканера, цикл совершает два шага. На каждом шаге система пытается обработать полученный штрихкод через настройки текущего в итерации сканера. Так как драйверы присылают одинаковое имя источника и одинаковые данные, 1С считает событие актуальным для обоих сканеров по очереди. В результате штрихкод обрабатывается дважды, и товар добавляется в табличную часть документа в двойном количестве. Проанализируем способы устранения этого поведения.
Если ваша конфигурация не стоит на жесткой поддержке и вы можете вносить изменения в программный код, то этот способ является самым простым и логичным. Мы изменим логику обработки события таким образом, чтобы при первой же успешной обработке штрихкода цикл опроса устройств немедленно завершался.
Для этого нам понадобится внести правки в общий модуль РаботаСТорговымОборудованием. Найдем функцию или процедуру, которая обходит подключенное торговое оборудование (обычно это функция ПолучитьПараметрыСканера или аналогичный обработчик событий).
Рассмотрим пример изменения кода:
// Стандартный обход подключенных устройств в цикле
Для Каждого СтрокаУстройства Из ТаблицаПодключенногоОборудования Цикл
Если СтрокаУстройства.Вид == Перечисления.ВидыТорговогоОборудования.СканерШтрихКода Тогда
// Программа вызывает обработку события для каждого сканера
РезультатОбработки = ОбработатьДанныеСканера(СтрокаУстройства, Данные);
// НАШЕ ИСПРАВЛЕНИЕ:
// Если штрихкод успешно распознан и обработан первым же сканером в списке,
// нет необходимости опрашивать остальные сканеры в рамках этого события.
Если РезультатОбработки = Истина Тогда
Прервать; // Выходим из цикла обхода
КонецЕсли;
КонецЕсли;
КонецЦикла;
Благодаря добавлению оператора Прервать, как только первый сканер из списка подключенных обработает полученное событие и добавит товар в документ, цикл немедленно остановится. Попытка опроса второго сканера для этого же события будет заблокирована, что полностью решит проблему задвоения.
Если вы используете для работы профессиональные драйверы оборудования от компании АТОЛ (например, версии 6.x, 8.x или более поздние), проблему дублирования можно решить исключительно на уровне настроек драйверов, вообще не прибегая к изменению кода конфигурации 1С.
Драйвер устройств ввода АТОЛ поддерживает концепцию работы с несколькими «Логическими Устройствами» (ЛУ). Мы можем настроить систему так, чтобы каждое физическое устройство имело свой собственный уникальный логический номер.
Разберем этот процесс по шагам:
При такой настройке внешняя компонента драйвера будет передавать в процедуру ВнешнееСобытие уникальные идентификаторы источников в зависимости от того, какое логическое устройство сработало. Система 1С сможет безошибочно сопоставить пришедший штрихкод с конкретным физическим сканером, не дублируя вызовы.
Если удваиваются данные при использовании абсолютно одинаковых драйверов, мы можем физически разделить обработку сигналов, заставив устройства работать через разные программные библиотеки.
Например, настроим следующую схему работы:
1С:Сканеры штрихкода (COM). Настраиваем его на виртуальный COM-порт устройства.АТOЛ: Драйвер устройств ввода).Поскольку разные программные библиотеки генерируют внешние события с существенно различающимися именами параметров Источник (например, компонента от 1С передает строку "BarCodeScan", а АТОЛ передает "AtolInputDevice"), типовой алгоритм обработки торгового оборудования в 1С четко разделит эти потоки. Каждый сканер будет обрабатывать исключительно свои собственные события, полностью исключая наложение данных друг на друга.
Этот способ незаменим, когда вносить изменения в общие модули торгового оборудования нельзя, а драйверы используются одинаковые. В этом случае мы перекладываем задачу идентификации сканеров на логику обработки внутри самого документа (или формы подбора) с помощью настройки префиксов в памяти самих устройств.
Схема реализации выглядит следующим образом:
"A"."B".Пример программного анализа префиксов в форме документа:
Процедура ВнешнееСобытие(Источник, Событие, Данные)
// Получаем строку данных от сканера
ВходныеДанные = СокрЛП(Данные);
ПервыйСимвол = Лев(ВходныеДанные, 1);
Если ПервыйСимвол = "A" Тогда
// Данные пришли от первого сканера. Отрезаем префикс и обрабатываем.
ЧистыйШтрихкод = Сред(ВходныеДанные, 2);
ОбработатьШтрихкодУстройства(ЧистыйШтрихкод, "Сканер_1");
ИначеЕсли ПервыйСимвол = "B" Тогда
// Данные пришли от второго сканера. Отрезаем префикс и обрабатываем.
ЧистыйШтрихкод = Сред(ВходныеДанные, 2);
ОбработатьШтрихкодУстройства(ЧистыйШтрихкод, "Сканер_2");
Иначе
// Обработка по умолчанию, если префикс не распознан
ОбработатьШтрихкодУстройства(ВходныеДанные, "Стандартный");
КонецЕсли;
КонецПроцедуры
Этот подход гарантирует абсолютную точность распределения данных. Программа всегда будет точно знать, с какого именно физического устройства пришел штрихкод, даже если они подключены к одному COM-порту или используют одинаковые библиотеки.
Если один из сканеров используется кассиром постоянно, а второй требуется лишь время от времени, можно настроить их работу в разных физических режимах передачи данных.
Для этого произведем следующие настройки:
ВнешнееСобытие и автоматически без лишних кликов добавлять товары в чек.F7) и произвести сканирование. Данные введутся в открывшееся окно как обычный текст с клавиатуры, после чего товар добавится в документ.Данная схема полностью исключает любые конфликты на уровне драйверов операционной системы и платформы 1С, так как устройства работают на принципиально разных уровнях абстракции ввода информации.