Как записывать штрихкоды со сканера в файл параллельно с 1С и решить проблему их потери при потере фокуса?

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

В процессе работы с торговым оборудованием, особенно в высоконагруженных точках продаж (РМК), системные администраторы и программисты часто сталкиваются с загадочным поведением сканеров штрихкодов: данные «теряются» по пути от устройства до документа 1С. Ситуация осложняется, когда кассир использует дополнительные мониторы для покупателей или сторонние приложения, из-за чего окно 1С может кратковременно терять фокус.

В данной статье мы подробно разберем, почему происходят потери данных при использовании COM-портов (RS-232), как организовать контрольный лог всех сканирований в текстовый файл и как правильно настроить программный код 1С для обработки событий даже в фоновом режиме. Мы проанализируем ситуацию на примере конфигурации 1С:Розница 1.0 на обычных формах, но данные принципы применимы к любым решениям на платформе 1С:Предприятие 8.

Различие в работе сканеров: Клавиатурный интерфейс vs COM-порт

Прежде всего, нам необходимо понять физику процесса. Сканеры могут подключаться в режиме «разрыва клавиатуры» (HID) или через эмуляцию COM-порта (RS-232). Рассмотрим особенности каждого метода:

  1. Клавиатурный ввод: Если сканер работает как клавиатура, данные попадают строго в то поле или окно, которое находится в активном фокусе Windows. Если в момент сканирования кассир переключился на другое окно, штрихкод будет «напечатан» там или просто потерян. Драйвер 1С в этом режиме перехватывает нажатия клавиш, но он также жестко привязан к активности приложения.
  2. COM-порт (RS-232): Это более профессиональный метод. Данные передаются в последовательный порт, который слушает драйвер 1С. Поток байтов поступает в операционную систему независимо от того, какое окно активно. Драйвер генерирует ВнешнееСобытие, которое 1С должна обработать.

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

Выявление причины потери данных: Ловушка функции ВводДоступен()

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


Процедура ВнешнееСобытие(Источник, Событие, Данные)
    
    // Проблемная проверка
    Если НЕ ВводДоступен() Тогда
        Возврат;
    КонецЕсли;

    // Далее идет логика обработки штрихкода...
КонецПроцедуры

Функция ВводДоступен() возвращает Ложь, если основное окно 1С не активно. Если ваш сканер подключен через COM, он исправно посылает данные, драйвер создает событие, но 1С мгновенно прерывает его выполнение из-за этой строки. Решение: для COM-сканеров эту проверку необходимо убрать. После удаления строки данные будут попадать в 1С даже в свернутом состоянии программы.

Как организовать параллельную запись всех сканов в файл

Для создания контрольного механизма (сравнения «что пикнуло» и «что попало в чек») нам нужно записывать данные в текстовый файл независимо от 1С. Рассмотрим три способа реализации этой задачи.

Способ 1: Использование специализированных утилит (Serial Port Monitor)

Если система 64-битная, классический Portmon может не запуститься. В этом случае мы рекомендуем использовать профессиональные решения для мониторинга COM-портов, такие как Advanced Serial Data Logger или аналоги. Эти программы умеют:

Способ 2: Программное разветвление порта (Serial Port Splitter)

Рассмотрим ситуацию, когда две программы не могут одновременно открыть один и тот же физический COM-порт. Для этого мы можем применить «разветвитель». Программное обеспечение (например, от FabulaTech) создает виртуальный мост. Физический COM1 превращается в два виртуальных — COM2 и COM3. К COM2 мы подключаем 1С, а к COM3 — простую утилиту, записывающую всё в файл. Это гарантирует отсутствие конфликтов доступа к железу.

Способ 3: Доработка логики 1С для логирования

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


Процедура ЗаписатьЛогСканера(Штрихкод)
    ТекстЛога = Новый ЗаписьТекста("C:\Logs\barcodes_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".txt", КодировкаТекста.UTF8, , Истина);
    СтрокаЗаписи = "" + ТекущаяДата() + " | " + Штрихкод;
    ТекстЛога.ЗаписатьСтроку(СтрокаЗаписи);
    ТекстЛога.Закрыть();
КонецПроцедуры

Процедура ВнешнееСобытие(Источник, Событие, Данные)
    Если Событие = "Barcode" Тогда
        // Сначала логируем событие в файл
        ЗаписатьЛогСканера(Данные);
        
        // Затем обрабатываем его в 1С
        ОбработатьШтрихкод(Данные);
    КонецЕсли;
КонецПроцедуры

Преимущество: Это решение не требует стороннего софта. Недостаток: Если 1С зависнет на выполнении тяжелого запроса, внешнее событие может не вызваться вовремя, и запись в файл не произойдет. Поэтому для критически важного аудита лучше использовать внешние утилиты из Способа 1.

Решение проблемы дублирования событий в модальных окнах

Когда мы убираем ВводДоступен(), возникает побочный эффект: если поверх РМК открыто модальное окно (например, выбор причины отмены чека), и в нем тоже есть обработка сканера, то штрихкод может обработаться дважды — и в основном окне, и в модальном. Разберем, как правильно управлять состоянием обработки:

Вместо отключения и подключения оборудования (что может привести к «отвалу» драйвера), мы рекомендуем использовать флаги активности. Посмотрим на алгоритм:

  1. Создаем экспортную переменную в модуле формы или глобальную переменную мНеОбрабатыватьСканер.
  2. Перед открытием любого дополнительного окна устанавливаем флаг в Истина.
  3. Во ВнешнемСобытии основной формы проверяем этот флаг.

Пример кода для основной формы РМК:


Перем мНеОбрабатыватьСканер;

Процедура ОткрытьОкноВозврата()
    мНеОбрабатыватьСканер = Истина;
    Форма = ПолучитьФорму("ФормаВыбораПричины");
    Форма.ОткрытьМодально();
    мНеОбрабатыватьСканер = Ложь;
КонецПроцедуры

Процедура ВнешнееСобытие(Источник, Событие, Данные)
    Если мНеОбрабатыватьСканер Тогда
        Возврат; // Игнорируем, так как открыто другое окно
    КонецЕсли;
    
    // Основная логика подбора товара
КонецПроцедуры

Нюансы буферизации данных

Проанализируем ситуацию, когда кассир сканирует товары очень быстро. Если 1С «задумалась» (например, при обращении к базе данных), события накапливаются в очереди сообщений Windows. Если буфер драйвера или самого порта переполнится, данные могут исказиться. Для минимизации рисков мы рекомендуем:

Таким образом, мы выяснили, что основная причина «пропажи» данных в 1С чаще всего кроется в программных проверках доступности ввода, а не в технических ограничениях порта. Используя предложенные методы логирования и управления флагами, вы сможете обеспечить 100% контроль за процессом сканирования и исключить человеческий фактор.

← На главную