Как подключить и обработать штрихкод со сканера в дополнительной форме РМК 1С:Розница?

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

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

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

Поиск правильного обработчика для получения штрихкода

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

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


&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ScanData" Тогда
        // Событие "ScanData" указывает на то, что были получены данные со сканера штрихкода.
        // Параметр[0] содержит сам штрихкод.
        Штрихкод = Параметр[0];
        
        // Далее следует ваш код для обработки полученного штрихкода.
        // Например, вы можете вывести его или использовать для поиска товара.
        Сообщить("Получен штрихкод в дополнительной форме: " + Штрихкод);
        
        // Пример использования: Поиск товара по штрихкоду.
        // Допустим, у нас есть функция на сервере для поиска.
        // НачатьПоискТовараПоШтрихкодуНаСервере(Штрихкод);
        
    КонецЕсли;
    // Можно обрабатывать и другие события оборудования, если это необходимо.
    // Например, события от фискального регистратора или весов.
    // Если ИмяСобытия = "FiscalData" Тогда
    //    ...
    // КонецЕсли;
КонецПроцедуры

Важно: Процедура ОбработкаОповещения должна быть размещена в модуле той формы, которая в данный момент должна быть "слушателем" событий от сканера. Если сканер подключен к форме, но в ее модуле нет этой процедуры, или она не обрабатывает ИмяСобытия = "ScanData", то штрихкод не будет перехвачен.

Решение проблемы с дополнительными (модальными) формами: Явное управление подключением сканера

Как верно подметили в обсуждении, основная загвоздка при работе со сканером в дополнительных формах РМК заключается в том, что события от оборудования продолжают приходить в основную форму. Это происходит потому, что сканер был инициализирован и подключен к основной форме, и система "помнит" ее как основного получателя событий. Для корректной работы нам потребуется вручную "переключать" сканер между формами.

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

  1. Шаг 1: Временно отключаем сканер от основной формы РМК

    Прежде чем открыть дополнительную форму, нам необходимо "освободить" сканер от привязки к основной форме РМК. Это гарантирует, что события не будут уходить в "никуда" (или в неактивную форму РМК) во время работы дополнительной формы. Отключение производится при помощи МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы().

    Этот код следует разместить в той процедуре основной формы РМК, которая отвечает за открытие дополнительной формы (например, в обработчике нажатия кнопки).

    
    &НаКлиенте
    Процедура ОткрытьДополнительнуюФормуИОтключитьСканер()
        // Отключаем сканер от текущей формы, чтобы он не перехватывал события,
        // пока активна дополнительная форма.
        МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
                
        // Определяем описание оповещения, которое будет вызвано после закрытия дополнительной формы.
        // Это нужно, чтобы мы могли снова подключить сканер к РМК.
        ОповещениеОЗакрытииФормы = Новый ОписаниеОповещения("ПослеЗакрытияДополнительнойФормы", ЭтотОбъект);
                
        // Открываем дополнительную форму.
        // Если форма модальная, можно использовать ОткрытьФормуМодально,
        // но в управляемом приложении чаще используют ОткрытьФорму с оповещением.
        ОткрытьФорму("Обработка.МояДополнительнаяФорма.Форма.Форма", , ЭтотОбъект, , , , ОповещениеОЗакрытииФормы);
    КонецПроцедуры
    

    Или, если вы используете модальный вызов (что не рекомендуется, но иногда бывает):

    
    &НаКлиенте
    Процедура ОткрытьДополнительнуюФормуМодально()
        // Отключаем сканер перед модальным открытием
        МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
                
        // Модальное открытие формы
        ОткрытьФормуМодально("Обработка.МояДополнительнаяФорма.Форма.Форма");
                
        // После закрытия модальной формы, сразу подключаем сканер обратно.
        // В случае модального открытия, оповещение не требуется, т.к. код ждет закрытия.
        ПодключитьСканерКОсновнойФорме();
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ПодключитьСканерКОсновнойФорме()
        ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершение", ЭтотОбъект);
        МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
            ОповещенияПриПодключении,
            ЭтотОбъект,
            "СканерШтрихкода");
    КонецПроцедуры
    
  2. Шаг 2: Подключаем сканер к дополнительной форме при ее открытии

    В процедуре ПриОткрытии или ПослеОткрытия дополнительной формы необходимо инициировать подключение сканера именно к этой форме. Это позволит ей стать активным получателем событий от сканера.

    
    // Модуль дополнительной формы (например, Обработка.МояДополнительнаяФорма.Форма.Форма)
            
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        // Инициируем асинхронное подключение сканера к ЭТОЙ форме.
        // "СканерШтрихкода" - это тип оборудования, который мы хотим подключить.
        ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершениеДополнительнаяФорма", ЭтотОбъект);
        МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
            ОповещенияПриПодключении,
            ЭтотОбъект,
            "СканерШтрихкода");
                
        // Здесь же можно вызвать обновление команд, если в форме есть кнопки,
        // связанные с подключаемым оборудованием.
        ПодключаемыеКомандыКлиент.НачатьОбновлениеКоманд(ЭтотОбъект); 
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ПодключитьОборудованиеЗавершениеДополнительнаяФорма(ПодключенныеОбъектыОборудования, ДополнительныеПараметры) Экспорт
        // Это обработчик завершения асинхронного подключения.
        // Здесь мы можем убедиться, что сканер действительно подключен.
        Если ПодключенныеОбъектыОборудования.Количество() > 0 Тогда
            Сообщить("Сканер успешно подключен к дополнительной форме.");
        Иначе
            Сообщить("Не удалось подключить сканер к дополнительной форме.");
        КонецЕсли;
    КонецПроцедуры
    

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

  3. Шаг 3: Обрабатываем штрихкод в дополнительной форме

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

    
    // Модуль дополнительной формы
            
    &НаКлиенте
    Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
        Если ИмяСобытия = "ScanData" Тогда
            Штрихкод = Параметр[0];
            Если НЕ ПустаяСтрока(Штрихкод) Тогда
                Сообщить("Штрихкод '" + Штрихкод + "' получен в дополнительной форме. Начинаем обработку...");
                        
                // Пример: Вызов серверной функции для поиска и обработки штрихкода
                // Например, если у вас есть табличная часть на форме, вы можете добавить туда товар
                // ОбработатьШтрихкодНаСервере(Штрихкод);
                        
                // Или, если вся логика на клиенте
                // НайтиИДобавитьТоварВТаблицу(Штрихкод);
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры
    
  4. Шаг 4: Отключаем сканер от дополнительной формы при ее закрытии

    Перед закрытием дополнительной формы крайне важно "освободить" сканер от ее привязки. Это позволит нам снова подключить его к основной форме РМК без конфликтов. Используем для этого процедуру ПриЗакрытии дополнительной формы.

    
    // Модуль дополнительной формы
            
    &НаКлиенте
    Процедура ПриЗакрытии(ЗавершениеРаботы)
        // Отключаем сканер от этой формы, чтобы основная форма могла его использовать.
        МенеджерОборудованияКлиент.ОтключитьОборудованиеОтФормы(ЭтотОбъект, "СканерШтрихкода");
        Сообщить("Сканер отключен от дополнительной формы.");
    КонецПроцедуры
    
  5. Шаг 5: Восстанавливаем подключение сканера к основной форме РМК

    После закрытия дополнительной формы (и, следовательно, после отключения от нее сканера), мы должны снова подключить сканер к основной форме РМК, чтобы продолжить работу в штатном режиме. Это делается в обработчике оповещения, который мы передали при открытии дополнительной формы.

    
    // Модуль основной формы РМК
            
    &НаКлиенте
    Процедура ПослеЗакрытияДополнительнойФормы(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
        // Вызывается после того, как дополнительная форма была закрыта.
        // Теперь мы можем снова подключить сканер к основной форме.
                
        ОповещенияПриПодключении = Новый ОписаниеОповещения("ПодключитьОборудованиеЗавершение", ЭтотОбъект);
        МенеджерОборудованияКлиент.НачатьПодключениеОборудованиеПриОткрытииФормы(
            ОповещенияПриПодключении,
            ЭтотОбъект,
            "СканерШтрихкода");
                
        Сообщить("Сканер повторно подключен к основной форме РМК.");
                
        // Это обработчик, который вызывается после завершения подключения к основной форме.
        // Можно использовать его для проверки успешности.
    КонецПроцедуры
    
    &НаКлиенте
    Процедура ПодключитьОборудованиеЗавершение(ПодключенныеОбъектыОборудования, ДополнительныеПараметры) Экспорт
        Если ПодключенныеОбъектыОборудования.Количество() > 0 Тогда
            Сообщить("Сканер успешно подключен к основной форме РМК.");
        Иначе
            Сообщить("Не удалось повторно подключить сканер к основной форме РМК.");
        КонецЕсли;
    КонецПроцедуры
    

Общие рекомендации

Таким образом, проблема обработки штрихкодов в дополнительных формах РМК решается не поиском "особой" процедуры для сканера, а правильным и явным управлением жизненным циклом подключения сканера к конкретной форме. Этот подход позволяет нам избежать конфликтов и обеспечивает стабильную работу с оборудованием в сложных пользовательских сценариях.

← На главную