Как обработать внешнее событие сканера штрихкодов в модальном окне 1С 7.7?

Программист 1С v7.7 Торговля и дистрибуция
← На главную

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

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

Причина блокировки сканера: почему «молчит» модальное окно?

Для того чтобы понять природу проблемы, разберем механизм взаимодействия платформы 1С 7.7 с внешними компонентами (например, ScanOPOS.dll или драйвером «АТОЛ»).

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

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

Теперь рассмотрим сценарий, который приводит к зависанию:

  1. Пользователь сканирует штрихкод в табличной части документа.
  2. Срабатывает внешнее событие, товар добавляется в строку.
  3. Следом срабатывает предопределенное событие ПриОкончанииРедактированияСтроки.
  4. Внутри этого события программный код вызывает открытие другой обработки (например, формы для ввода кодов маркировки «Честный Знак») в модальном режиме.
  5. Поскольку окно открывается модально, выполнение основного потока программы мгновенно замораживается на строке вызова формы. Программа просто «не успевает» дойти до вызова финальной функции глСканерПосылкаДанных(1) в основной форме.
  6. Драйвер сканера остается заблокированным. Физически сканер может издавать звуковой сигнал при сканировании маркировки, но внешнее событие в новое модальное окно не передается, так как порт заблокирован на уровне драйвера.

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

Самое простое и элегантное решение этой проблемы — принудительно сообщить драйверу сканера штрихкодов о готовности принимать данные сразу же в момент инициализации нового модального окна.

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

Рассмотрим пример реализации кода в модуле модальной формы:


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

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

Ограничение платформы: Ошибка «Открытие окна в данном режиме недоступно»

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

Для обхода этой проблемы рассмотрим два классических и надежных метода.

Метод 1: «Ложное закрытие формы»

Это классический прием («костыль») разработчиков под 1С 7.7, позволяющий выйти из заблокированного транзакционного контекста предопределенной процедуры, выполнить интерактивное действие и вернуть пользователя обратно.

Суть метода заключается в том, что мы имитируем закрытие основной формы документа с помощью метода Форма.Закрыть(0), предварительно установив специальный флаг. В процедуре ПриЗакрытии() мы перехватываем этот флаг, выполняем открытие нашего модального окна и затем отменяем само закрытие основной формы с помощью функции СтатусВозврата(0).

Разберем по шагам реализацию этого механизма:

Шаг 1. В модуле формы документа в разделе описания переменных объявляем флаг ложного закрытия:

Перем ФлЛожноеЗакрытие;

Шаг 2. В процедуре ПриОкончанииРедактированияСтроки взводим флаг и инициируем закрытие формы:


Процедура ПриОкончанииРедактированияСтроки(П1, П2)
    // Проверяем, нужно ли запросить маркировку для товара
    Если ТекущийДокумент.Товар.ТребуетМаркировки = 1 Тогда
        ФлЛожноеЗакрытие = 1;
        Форма.Закрыть(0); // Запускаем цепочку закрытия формы
    КонецЕсли;
КонецПроцедуры

Шаг 3. В предопределенной процедуре ПриЗакрытии() обрабатываем поведение формы:


Процедура ПриЗакрытии()
    Если ФлЛожноеЗакрытие = 1 Тогда
        ФлЛожноеЗакрытие = 0; // Сбрасываем флаг, чтобы не зациклиться
        
        // Открываем модальное окно маркировки. 
        // Контекст выполнения уже свободен от ограничений редактирования строки!
        ОткрытьФормуМодально("Обработка.ВводМаркировки", Контекст);
        
        СтатусВозврата(0); // Отменяем реальное закрытие основной формы!
        Возврат;
    КонецЕсли;
КонецПроцедуры

Этот метод гарантированно обходит любые блокировки интерфейса платформы 1С 7.7, позволяя открывать любые диалоги.

Метод 2: Использование «Обработки ожидания» (Таймера)

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

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

Рассмотрим пример реализации через таймер:


Процедура ПриОкончанииРедактированияСтроки(П1, П2)
    Если ТекущийДокумент.Товар.ТребуетМаркировки = 1 Тогда
        // Запускаем процедуру "ОткрытьОкноВводаМаркировки" через 1 секунду
        Форма.ОбработкаОжидания("ОткрытьОкноВводаМаркировки", 1);
    КонецЕсли;
КонецПроцедуры

Процедура ОткрытьОкноВводаМаркировки()
    // Первым делом отключаем обработку ожидания, чтобы она не срабатывала циклически
    Форма.ОбработкаОжидания("", 0);
    
    // Теперь мы можем безопасно открыть модальное или немодальное окно
    ОткрытьФормуМодально("Обработка.ВводМаркировки", Контекст);
КонецПроцедуры

Метод 3: Использование внешних компонент (FormEx)

Для глубокой модернизации интерфейса 1С 7.7 профессиональные разработчики используют внешнюю компоненту FormEx. Она позволяет перехватывать события клавиатуры, мыши и фокуса ввода в обход стандартных ограничений платформы.

С помощью компоненты FormEx можно отслеживать событие ПослеОбновленияФормы(). Это событие генерируется платформой автоматически сразу после того, как 1С закончила перерисовку элементов интерфейса и вышла из любых обработчиков событий табличной части. Использование этого события избавляет от необходимости применять костыли в виде ложного закрытия формы или таймеров.

Заключение

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

← На главную