Как из 1С получить сумму денежных средств в кассе ККТ АТОЛ без печати отчета

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

При автоматизации розничной торговли часто возникает необходимость оперативно получать данные о состоянии кассы прямо в интерфейсе 1С. Например, перед проведением выемки или для контроля текущей выручки. Популярное решение «распечатать X-отчет» подходит далеко не всегда, так как это расходует чековую ленту и отвлекает кассира. Разберем детально, как получить точную сумму наличных в денежном ящике ККТ АТОЛ программными методами из 1С с использованием Драйвера торгового оборудования 10-й версии (ДТО 10).

Метод 1. Прямое обращение через COM-объект ДТО 10

Рассмотрим классический способ интеграции, основанный на обращении к драйверу ККТ как к COM-объекту. Этот метод подходит для операционных систем семейства Windows при работе в 32-разрядных или 64-разрядных клиентах 1С.

Ниже представлен готовый код функции, которую можно использовать во внешней обработке или модуле конфигурации для прямого запроса к кассовому аппарату:


Функция ПолучитьСуммуВКассеАТОЛ() Экспорт
    СуммаВДЯ = 0;
    
    // Инициализируем COM-объект драйвера АТОЛ 10
    Попытка
        fptr = Новый COMОбъект("AddIn.Fptr10");
    Исключение
        ЗаписьЖурналаРегистрации("ККТ_АТОЛ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Не удалось создать объект драйвера AddIn.Fptr10. Проверьте регистрацию DLL.");
        ВызватьИсключение "Драйвер ККТ АТОЛ 10 не зарегистрирован в системе!";
    КонецПопытки;
    
    // Настраиваем подключение. В данном примере используется порт USB.
    // Если подключение идет по COM-порту, настройки будут другими (рассмотрим ниже).
    fptr.setSingleSetting(fptr.LIBFPTR_SETTING_PORT, Строка(fptr.LIBFPTR_PORT_USB));
    fptr.applySingleSettings();
    
    // Открываем соединение с ККТ
    fptr.open();
    
    Если fptr.isOpened() Тогда
        Попытка
            // Устанавливаем параметр запроса: получение суммы наличных в денежном ящике
            fptr.setParam(fptr.LIBFPTR_PARAM_DATA_TYPE, fptr.LIBFPTR_DT_CASH_SUM);
            fptr.queryData();
            
            // Считываем полученное значение
            СуммаВДЯ = fptr.getParamDouble(fptr.LIBFPTR_PARAM_SUM);
        Исключение
            ЗаписьЖурналаРегистрации("ККТ_АТОЛ", УровеньЖурналаРегистрации.Предупреждение, , , 
                "Ошибка при чтении данных из ККТ: " + fptr.errorDescription());
        КонецПопытки;
        
        // Обязательно закрываем соединение с устройством, чтобы освободить порт
        fptr.close();
    Иначе
        ЗаписьЖурналаРегистрации("ККТ_АТОЛ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Не удалось открыть порт ККТ: " + fptr.errorDescription());
    КонецЕсли;
    
    // Очищаем COM-объект из памяти
    fptr = Неопределено;
    
    Возврат СуммаВДЯ;
КонецФункции

Регистрация компоненты в системе и устранение ошибки 0x800401F3

Выясним причину популярной ошибки: «Недопустимая строка с указанием класса (0x800401F3)», которая часто возникает при попытке выполнить строку fptr = Новый COMОбъект("AddIn.Fptr10"). Данная ошибка означает, что операционная система Windows не знает о существовании класса AddIn.Fptr10, так как библиотека драйвера не зарегистрирована в реестре.

Для устранения этой проблемы выполним следующие шаги по шагам:

  1. Перейдем в каталог установки драйвера АТОЛ. Обычно файлы для интеграции находятся по пути: C:\Program Files\ATOL\Drivers10\KKT\Langs\com\ (или Program Files (x86) для 32-битной версии).
  2. Определим разрядность вашего приложения 1С. Помните, что разрядность библиотеки должна строго соответствовать разрядности исполняемого файла 1С, который вызывает этот код:
    • Если у вас запущен 32-разрядный клиент 1С (даже на 64-битной Windows), используем файл addin_fptr10_x86.dll.
    • Если у вас запущен 64-разрядный клиент 1С или код выполняется на сервере под управлением 64-разрядной службы «1С:Предприятие», используем файл addin_fptr10_x64.dll.
  3. Запустим командную строку (cmd) обязательно от имени Администратора.
  4. Выполним команду регистрации библиотеки. Например, для 32-разрядной версии: regsvr32 "C:\Program Files\ATOL\Drivers10\KKT\Langs\com\addin_fptr10_x86.dll" Или для 64-разрядной версии: regsvr32 "C:\Program Files\ATOL\Drivers10\KKT\Langs\com\addin_fptr10_x64.dll"
  5. После появления сообщения об успешной регистрации перезапустим сеанс 1С и проверим работоспособность кода.

Метод 2. Кроссплатформенное подключение через Native API

Использование технологии COM имеет существенный недостаток: оно жестко привязано к Windows и требует ручной регистрации библиотек с правами администратора на каждом рабочем месте. Разберем более современный альтернативный вариант подключения драйвера АТОЛ через технологию Native API.

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


Функция ПолучитьСуммуВКассеNativeAPI(ПутьККомпоненте) Экспорт
    СуммаВДЯ = 0;
    
    // Подключаем внешнюю компоненту по технологии Native API без обращения к реестру
    РезультатПодключения = ПодключитьВнешнююКомпоненту(ПутьККомпоненте, "Fptr10", ТипВнешнейКомпоненты.Native);
    
    Если РезультатПодключения Тогда
        Попытка
            // Создаем объект ККТ
            fptr = Новый("AddIn.Fptr10.Fptr10");
        Исключение
            ВызватьИсключение "Не удалось инициализировать объект Native API AddIn.Fptr10.Fptr10";
        КонецПопытки;
        
        // Настройка параметров подключения и работа с ККТ аналогична COM-варианту
        fptr.setSingleSetting(fptr.LIBFPTR_SETTING_PORT, Строка(fptr.LIBFPTR_PORT_USB));
        fptr.applySingleSettings();
        
        fptr.open();
        Если fptr.isOpened() Тогда
            fptr.setParam(fptr.LIBFPTR_PARAM_DATA_TYPE, fptr.LIBFPTR_DT_CASH_SUM);
            fptr.queryData();
            СуммаВДЯ = fptr.getParamDouble(fptr.LIBFPTR_PARAM_SUM);
            fptr.close();
        КонецЕсли;
        
        fptr = Неопределено;
    КонецЕсли;
    
    Возврат СуммаВДЯ;
КонецФункции

В качестве параметра ПутьККомпоненте можно передавать как прямой путь к файлу fptr10.dll на диске, так и использовать макет внешней компоненты, упакованный в ZIP-архив с манифестом, что позволит платформе 1С автоматически подбирать нужную разрядность библиотеки под текущее окружение клиента или сервера.

Метод 3. Получение суммы наличных через БСП (без низкоуровневого кода)

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

Интеграционная компонента 1С поддерживает отправку XML-запросов и получение детального статуса ККТ. Проанализируем пример получения данных через стандартные методы БСП:


Функция ПолучитьСуммуВКассеЧерезБСП(ИдентификаторУстройства)
    СуммаНаличных = 0;
    
    // Получаем объект драйвера из подсистемы БСП "ПодключаемоеОборудование"
    ПараметрыПодключения = Новый Структура;
    РезультатВыполнения = ПодключаемоеОборудованиеРТ.ПолучитьПараметрыПодключения(ИдентификаторУстройства, ПараметрыПодключения);
    
    Если РезультатВыполнения Тогда
        // Подключаем устройство программно средствами 1С
        РезультатПодключения = МенеджерОборудованияКлиент.ПодключитьУстройство(ИдентификаторУстройства);
        
        Если РезультатПодключения Тогда
            ПараметрыККТ = "";
            // Запрашиваем состояние ККТ. Метод возвращает XML-структуру с полными данными ККТ
            РезультатЗапроса = МенеджерОборудованияКлиент.ВыполнитьКоманду(
                ИдентификаторУстройства, 
                "GetStatus", 
                Новый Массив, 
                ПараметрыККТ
            );
            
            Если РезультатЗапроса Тогда
                // Читаем XML и ищем тег CashDrawer (Денежный ящик)
                ЧтениеXML = Новый ЧтениеXML;
                ЧтениеXML.УстановитьСтроку(ПараметрыККТ);
                Пока ЧтениеXML.Прочитать() Цикл
                    Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "CashDrawer" Тогда
                        // Считываем сумму наличных в денежном ящике
                        СуммаНаличных = Число(ЧтениеXML.ПолучитьАтрибут("CashSum"));
                        Прервать;
                    КонецЕсли;
                КонецЦикла;
            КонецЕсли;
            
            // Обязательно отключаем ККТ средствами 1С, чтобы освободить порт для других сеансов
            МенеджерОборудованияКлиент.ОтключитьУстройство(ИдентификаторУстройства);
        КонецЕсли;
    КонецЕсли;
    
    Возврат СуммаНаличных;
КонецФункции

Как обойти конфликт «Порт занят» при параллельной работе ККТ

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

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

  1. Программное освобождение порта в 1С перед прямым вызовом ККТ: перед созданием своего объекта драйвера мы можем вызвать отключение оборудования через БСП методом МенеджерОборудованияКлиент.ОтключитьУстройство(Ид), выполнить низкоуровневую операцию получения суммы, закрыть свой драйвер методом fptr.close(), а затем вернуть кассу в управление 1С вызовом МенеджерОборудованияКлиент.ПодключитьУстройство(Ид).
  2. Переход на работу через Веб-сервер АТОЛ (JSON): ДТО 10 включает в себя встроенный локальный веб-сервер. Вместо прямого подключения к USB/COM портам, мы настраиваем кассу на работу по протоколу HTTP (через JSON-запросы). Веб-сервер АТОЛ самостоятельно управляет очередью задач к ККТ, что исключает любые конфликты монопольного доступа к оборудованию.

Поиск и перечисление всех касс на компьютере

Разберем ситуацию, когда к одной рабочей станции подключено несколько кассовых аппаратов, и нам необходимо программно определить порты подключения или серийные номера ККТ. В драйверах ДТО 10 механизм поиска устройств претерпел значительные изменения по сравнению со старыми версиями. Посмотрим, как реализовать опрос портов на уровне кода 1С:


Процедура НайтиПодключенныеКассы()
    fptr = Новый COMОбъект("AddIn.Fptr10");
    
    // Запускаем процесс фонового поиска устройств на всех доступных портах
    fptr.searchDevices();
    
    // Организуем цикл для перебора всех найденных касс
    Пока fptr.nextDevice() Цикл
        // Получаем детальную информацию о каждом обнаруженном устройстве
        СерийныйНомер = fptr.getParamString(fptr.LIBFPTR_PARAM_SERIAL_NUMBER);
        ИмяПорта      = fptr.getParamString(fptr.LIBFPTR_PARAM_PORT_NAME);
        МодельККТ     = fptr.getParamString(fptr.LIBFPTR_PARAM_MODEL_NAME);
        
        Сообщить(СтрШаблон("Найден аппарат: %1, Серийный номер: %2, Порт подключения: %3", 
            МодельККТ, СерийныйНомер, ИмяПорта));
    КонецЦикла;
    
    fptr = Неопределено;
КонецПроцедуры

Таким образом, мы детально проанализировали различные варианты решения задачи: от прямого низкоуровневого обращения к драйверу ККТ через COM-соединение до использования кроссплатформенных технологий Native API и встроенной логики БСП. Выбор конкретного метода зависит от архитектуры вашей информационной системы, требований к кроссплатформенности и необходимости поддержки нескольких кассовых аппаратов на одном рабочем месте.

← На главную