Почему возникает ошибка «Порт занят» при пробитии чека на АТОЛ 11Ф в 1С и как её исправить

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

При эксплуатации фискальных регистраторов (например, АТОЛ 11Ф) в конфигурации «Управление торговлей» (редакция 10.3) кассиры или операторы могут сталкиваться со следующей ошибкой:

«АТОЛ 11Ф: Ошибка при подключении устройства. Необходимо убедиться, что устройство правильно настроено и соответствующий порт не занят другим приложением. Порт занят»

Характерная особенность этой проблемы — она проявляется эпизодически, например, при попытке пробить чек на товар с отрицательным остатком. При этом обычный перезапуск кассового модуля не помогает, и касса становится доступной только спустя 5–10 минут. Разберем подробнее, почему так происходит и как правильно доработать алгоритмы 1С для предотвращения подобного поведения.

Причина блокировки COM-порта

Протокол передачи данных по интерфейсу RS-232 (а также его виртуальной эмуляции через USB VCOM) является монопольным. Это означает, что в один момент времени работать с портом устройства может только один процесс или поток через установленное соединение.

Взаимодействие 1С с ККТ происходит по следующей базовой схеме:

  1. Выполняется метод подключения торгового оборудования (занимается и блокируется COM-порт внешней компонентой драйвера).
  2. Формируется и передается команда пробития чека на фискальный регистратор.
  3. Выполняется метод отключения оборудования (COM-порт освобождается внешней компонентой).

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

При повторной попытке пробить чек 1С снова пытается занять тот же порт, но получает отказ от операционной системы или драйвера, так как предыдущее соединение не было закрыто. Порт освобождается сам лишь по истечении системного таймаута удержания дескриптора (обычно от 5 до 10 минут).

Вариант 1. Перенос проверок остатков до вызова торгового оборудования

Наиболее эффективный подход — не подключаться к фискальному регистратору до тех пор, пока не пройдут все необходимые валидации документа. Проанализируем правильный порядок действий:

  1. Проверить остатки товаров на складе.
  2. Проверить корректность заполнения реквизитов документа, цен и сумм.
  3. Если есть ошибки — вывести предупреждение кассиру и прервать обработку до вызова функций работы с ККТ.
  4. Если все проверки пройдены — подключить оборудование, пробить чек и сразу отключить оборудование.

Вариант 2. Гарантированное отключение ККТ в блоке «Попытка ... Исключение»

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

Рассмотрим пример правильного оформления кода отключения оборудования при работе с механизмом Торгового Оборудования (ТО):


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

    // Проверка остатка номенклатуры
    Если ОстатокНаСкладе < КоличествоКПродаже Тогда
        ВызватьИсключение "Недостаточно товара на складе!";
    КонецЕсли;

    // Логика печати чека
    ПробитьЧекНаККТ(ДокументПродажи);

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

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


Процедура ОтключитьОборудование(Клиент)
    ТО = ПолучитьТО();
    Клиенты = ПолучитьПараметрСервераТО("Клиенты", "Соответствие");
    
    СтруктураПоиска = Новый Структура("Вид");
    Для Каждого ВидТО Из Перечисления.ВидыТорговогоОборудования Цикл
        Если Клиент.ПоддерживаетсяВидТО(ВидТО) Тогда
            СтруктураПоиска.Вид = ВидТО;
            СтрокиТО = ТО.НайтиСтроки(СтруктураПоиска);
            Для Каждого СтрокаТО Из СтрокиТО Цикл
                Если СтрокаТО.Ссылки = 1 Тогда
                    СтрокаТО.Ссылки = 0;
                    // Явный вызов отключения драйвера ККТ для освобождения COM-порта
                    СтрокаТО.Обработка.Отключить(СтрокаТО.Объект);
                ИначеЕсли СтрокаТО.Ссылки > 1 Тогда
                    СтрокаТО.Ссылки = СтрокаТО.Ссылки - 1;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    
    Клиенты.Удалить(Клиент);
КонецПроцедуры

Альтернативные способы решения аппаратных конфликтов

Если программный код 1С полностью исправен, но ошибка периодически повторяется, стоит проверить системные настройки подключения кассового аппарата:

  1. Настройка службы Ethernet over USB (EoU): При подключении АТОЛ по USB создаются два виртуальных COM-порта. Один используется 1С для отправки команд, второй — службой EoU для передачи данных в ОФД. Убедитесь, что служба EoU в файле settings.xml обращается именно к выделенному для ОФД порту и не пытается занять рабочий порт 1С.
  2. Переход на драйвер ДТО 10: Устаревшие версии драйверов (DTO 8) чаще подвержены зависанию виртуальных портов. Переход на актуальный драйвер АТОЛ 10-й версии и использование механизмов EoT (Ethernet over Transport) позволяет передавать данные в ОФД по тому же каналу, исключая конфликт двух COM-портов.
  3. Использование подключения по TCP/IP: При наличии на фискальном регистраторе сетевого интерфейса Ethernet переведите ККТ на работу по протоколу TCP/IP. Это позволит избавиться от нестабильности виртуальных COM-портов Windows.
← На главную