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

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

При переносе механизмов работы с торговым оборудованием из типовых конфигураций (например, Управление торговлей 10.3) в самописные или другие нетиповые решения разработчики часто сталкиваются с неприятной проблемой. Сканер штрихкодов успешно подключается, проходит тест в настройках, и даже корректно считывает первый штрихкод, добавляя товар в документ. Однако после первого сканирования внешнее событие полностью пропадает: последующие сканирования не вызывают никакой реакции в 1С, а отладчик даже не заходит в процедуру ВнешнееСобытие. Помогает только закрытие и повторное открытие формы документа.

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

---

Причина 1. Отсутствие предопределенного обработчика в модуле приложения

Это наиболее распространенная ошибка при ручном переносе кода торгового оборудования. Платформа 1С:Предприятие обрабатывает внешние события от внешних компонент (драйверов) по строгой цепочке передачи вызовов.

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

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

Решение:

Проверим наличие и перенесем в Модуль обычного приложения следующий обработчик:


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

---

Причина 2. Необходимость сброса состояния драйвера (ПосылкаДанных)

Многие драйверы сканеров штрихкодов (особенно популярные драйверы от компании «АТОЛ» старых версий или специализированные компоненты под COM-порты) работают по принципу монопольного владения событием. Чтобы защитить систему от лавинообразного засыпания порта данными, драйвер после считывания ШК блокирует передачу последующих кодов до тех пор, пока конфигурация явно не подтвердит готовность принять следующее событие.

В типовых обработках обслуживания этот сброс происходит автоматически внутри кода самой обработки. Но если вы используете нетиповой код или напрямую обращаетесь к свойствам драйвера в обход БПО (Библиотеки подключаемого оборудования), вам необходимо принудительно сообщать драйверу о завершении обработки.

Решение:

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


// Обращаемся к объекту драйвера и сбрасываем признак посылки данных
Объект.Драйвер.ПосылкаДанных = 0;

Для других современных драйверов, работающих по технологии NativeApi, может потребоваться включение флага приема новых событий:

Объект.Драйвер.DataEventEnabled = 1; // или Истина ---

Причина 3. Блокировка драйвера из-за использования точек останова (отладка)

Часто разработчики сами создают иллюзию проблемы во время тестирования кода. Если при первом сканировании вы поставили точку останова (breakpoint) внутри процедуры ВнешнееСобытие, вы прерываете асинхронный поток выполнения программы 1С.

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

Решение:

Не используйте точки останова для отладки торгового оборудования. Вместо этого используйте запись логов. Проанализируем пример логирования:


Процедура ВнешнееСобытие(Источник, Событие, Данные)
    
    // Записываем событие в Журнал регистрации для анализа без остановки потока
    ЗаписьЖурналаРегистрации("СканерШтрихкодов",
        УровеньЖурналаРегистрации.Информация,
        ,
        ,
        "Получены данные: " + Данные + " Источник: " + Источник);
        
    // Код обработки поиска номенклатуры...
    
КонецПроцедуры

---

Причина 4. Проверка доступности ввода формы (ВводДоступен)

В процедурах обработки внешних событий форм документов практически всегда присутствует стандартная проверка платформы на доступность интерактивного ввода. Выглядит она так:


Если Не ВводДоступен() Тогда 
    Возврат; 
КонецЕсли;

Выясним причину, почему это может заблокировать повторное сканирование:

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

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

Решение:

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

---

Причина 5. Нарушение триады подключения клиента торгового оборудования

Для корректной работы торгового оборудования в любой форме должен строго соблюдаться жизненный цикл подключения клиента ТО. Он состоит из трех обязательных шагов:

  1. Подключение клиента: происходит строго в процедуре ПриОткрытии формы.
  2. Обработка события: происходит в процедуре ВнешнееСобытие формы.
  3. Отключение клиента: происходит строго в процедуре ПриЗакрытии формы.

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

Убедитесь, что в модуле вашей формы прописаны все три шага:


Процедура ПриОткрытии()
    
    // Шаг 1. Подключаем форму к серверу торгового оборудования
    Если ПолучитьСерверТО() <> Неопределено Тогда
        ПолучитьСерверТО().ПодключитьКлиента(ЭтаФорма);
    КонецЕсли;
    
КонецПроцедуры

Процедура ВнешнееСобытие(Источник, Событие, Данные)
    
    // Шаг 2. Обрабатываем событие
    // (Код обработки данных)
    
КонецПроцедуры

Процедура ПриЗакрытии()
    
    // Шаг 3. Обязательно отключаем форму при закрытии
    Если ПолучитьСерверТО() <> Неопределено Тогда
        ПолучитьСерверТО().ОтключитьКлиента(ЭтаФорма);
    КонецЕсли;
    
КонецПроцедуры

Соблюдение этих правил и последовательная проверка каждого из пяти пунктов гарантированно вернут стабильную работу сканера штрихкодов в вашей конфигурации 1С.

← На главную