Как подключить онлайн-кассу к старой конфигурации «1С:Управление торговлей 10.2»

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

При работе со старыми конфигурациями 1С, такими как «Управление торговлей 10.2» (и даже ранние релизы 10.3), разработчики часто сталкиваются с серьезной проблемой: штатные механизмы торгового оборудования давно не обновлялись и физически не поддерживают требования актуального законодательства (54-ФЗ, ФФД 1.05 и 1.2), а также новые модели оборудования. Попытки перенести подсистему торгового оборудования из современных конфигураций часто заканчиваются путаницей в коде и зря потраченным временем.

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

Шаг 1. Выбор и загрузка внешней компоненты

В старых версиях конфигураций для работы с торговым оборудованием использовался метод ЗагрузитьВнешнююКомпоненту(). Этот метод часто дает сбои на современных операционных системах и требует обязательной регистрации библиотек в реестре Windows через утилиту regsvr32. Чтобы избежать этих проблем, мы рекомендуем использовать более надежный и современный метод платформы — ПодключитьВнешнююКомпоненту().

Для интеграции касс АТОЛ можно использовать два пути в зависимости от установленной версии драйверов торгового оборудования (ДТО):

  1. Использование ДТО 8 (устаревшая версия): Подходит для касс, работающих на старой платформе АТОЛ. Использует программный идентификатор AddIn.FprnM45 (или библиотеку FprnM1C82_54FZ.dll для совместимости с 54-ФЗ).
  2. Использование ДТО 10 (современная версия): Рекомендуемый вариант для новых касс (включая АТОЛ 30Ф, 22ПТК на Платформе 5.0). Использует программный идентификатор AddIn.Fptr10.

Рассмотрим пример инициализации драйвера в коде. Мы можем разместить этот код непосредственно в модуле формы документа «Чек ККМ» или в глобальном модуле для повторного использования:


// Попытка подключения компоненты ДТО 10
ПрогИД = "AddIn.Fptr10";
Подключено = ПодключитьВнешнююКомпоненту(ПрогИД);

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

Если Подключено Тогда
    Драйвер = Новый (ПрогИД);
    Сообщить("Внешняя компонента ККМ успешно подключена!");
Иначе
    ВызватьИсключение "Не удалось загрузить внешнюю компоненту ККМ. Проверьте установку драйверов!";
КонецЕсли;

Шаг 2. Решение проблемы разрядности (32-бит против 64-бит)

Если при выполнении приведенного выше кода вы получаете ошибку «Не удалось загрузить внешнюю компоненту», выясним причину этой неполадки. В 90% случаев это связано с несовпадением разрядности технологической платформы 1С и установленного драйвера АТОЛ.

Старые конфигурации на обычных формах (УТ 10.2) запускаются под управлением 32-битного клиента 1С:Предприятие. Даже если у вас установлена 64-разрядная операционная система Windows, для работы с кассой вам необходимо скачать и установить именно 32-битный дистрибутив Драйвера ККТ АТОЛ (installer с суффиксом x86 или windows32). При установке драйвера все необходимые COM-объекты автоматически зарегистрируются в операционной системе, и ручной вызов утилиты regsvr32 не понадобится.

Шаг 3. Программная настройка порта и скорости связи

В сообщении форума автор столкнулся со сложностями при попытке настроить параметры подключения (номер COM-порта и скорость обмена) напрямую из кода. Рассмотрим, как это сделать правильно.

Если вы используете современный ДТО 10, параметры связи передаются объекту драйвера перед открытием соединения с помощью специальных методов. Это избавляет от необходимости предварительно настраивать кассу через утилиту «Тест драйвера ККТ»:


// Установка типа подключения (COM-порт)
Драйвер.setSingleSetting(Драйвер.LIBFPTR_SETTING_PORT, Строка(Драйвер.LIBFPTR_PORT_COM));

// Задаем номер порта и скорость обмена данными
Драйвер.setSingleSetting(Драйвер.LIBFPTR_SETTING_COM_PORT, "COM3"); // Укажите ваш порт, к которому подключена ККТ
Драйвер.setSingleSetting(Драйвер.LIBFPTR_SETTING_BAUDRATE, Строка(Драйвер.LIBFPTR_PORT_SPEED_115200));

// Применяем настройки и открываем сессию связи с устройством
Драйвер.applySingleSettings();
Драйвер.open();

Если Не Драйвер.isOpened() Тогда
    Сообщить("Ошибка связи с ККТ: " + Драйвер.errorDescription());
КонецЕсли;

Если ККТ подключена по интерфейсу USB, современные драйверы поддерживают автоматический поиск устройства. Для этого достаточно указать тип порта USB:


Драйвер.setSingleSetting(Драйвер.LIBFPTR_SETTING_PORT, Строка(Драйвер.LIBFPTR_PORT_USB));
Драйвер.applySingleSettings();
Драйвер.open();

Шаг 4. Борьба с аннулированием чеков: скидки и округление

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

Современные кассовые аппараты, работающие по стандартам 54-ФЗ, производят жесткий арифметический контроль по каждой позиции чека. Должно соблюдаться строгое равенство до копейки:

(Цена * Количество) - Скидка = Сумма строки

В старых версиях «1С:Управление торговлей 10.2» расчет скидок в документе часто происходит по сложному алгоритму распределения накладных расходов или суммовых скидок на весь документ. В результате деления конечной суммы на количество товара могут получаться бесконечные периодические дроби (например, при продаже 3 штук товара на общую сумму 100 рублей цена одной штуки составит 33.3333... рублей). 1С округляет цену в чеке до двух знаков (33.33), перемножает на количество (3) и получает 99.99 рублей. Из-за расхождения в 1 копейку ККТ мгновенно бракует и аннулирует чек.

Проанализируем два надежных способа решения этой проблемы:

Способ А. Отказ от передачи скидок как отдельных параметров

Самый простой и эффективный способ для старых конфигураций — передавать в ККТ позиции номенклатуры уже с учетом всех примененных скидок. То есть мы передаем в драйвер скорректированную конечную цену товара, а параметр «Скидка» всегда оставляем равным нулю.

Способ Б. Разбиение строк номенклатуры при дробных расчетах

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

Пример: Вместо передачи одной строки «Товар Х — 3 шт. по цене 33.3333 руб. на сумму 100 руб.», мы передаем в ККТ две строки:

Сумма чека сойдется идеально (66.66 + 33.34 = 100.00), и ККТ успешно напечатает фискальный документ.

Шаг 5. Передача обязательных реквизитов (Теги 54-ФЗ)

По закону 54-ФЗ касса обязана содержать реквизиты кассира (ФИО и ИНН), а также иметь возможность отправки электронного чека покупателю (на email или телефон). Ниже приведен пример того, как передать эти данные в драйвер перед открытием документа.


// Передача ФИО и ИНН кассира (Обязательные теги 1021 и 1203)
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_CASHIER_NAME, "Иванов Иван Иванович");
Драйвер.setParam(Драйвер.LIBFPTR_PARAM_CASHIER_INN, "771234567890");
Драйвер.operatorLogin();

// Передача контактов покупателя для отправки SMS или Email (Тег 1008)
// Значением может быть телефон в формате +79991112233 или адрес почты
КонтактПокупателя = "client@example.com"; 
Если Не ПустаяСтрока(КонтактПокупателя) Тогда
    Драйвер.setParam(Драйвер.LIBFPTR_PARAM_CLIENT_CONTACT, КонтактПокупателя);
КонецЕсли;

Шаг 6. Шаблон готовой процедуры пробития чека

Сведем все полученные знания в единую готовую процедуру, которую вы сможете вставить в модуль документа «Чек ККМ» вашей конфигурации «Управление торговлей 10.2».


Процедура ПробитьЧекНаККТ() Экспорт

    // 1. Инициализация компоненты ДТО 10
    Если Не ПодключитьВнешнююКомпоненту("AddIn.Fptr10") Тогда
        Предупреждение("Компонента АТОЛ ДТО 10 не найдена на компьютере!");
        Возврат;
    КонецЕсли;
    
    Касса = Новый COMОбъект("AddIn.Fptr10");
    
    // 2. Настройка соединения
    Касса.setSingleSetting(Касса.LIBFPTR_SETTING_PORT, Строка(Касса.LIBFPTR_PORT_USB));
    Касса.applySingleSettings();
    Касса.open();
    
    Если Не Касса.isOpened() Тогда
        Предупреждение("Не удалось открыть порт ККТ: " + Касса.errorDescription());
        Возврат;
    КонецЕсли;
    
    Попытка
        // 3. Регистрация кассира
        Касса.setParam(Касса.LIBFPTR_PARAM_CASHIER_NAME, "Администратор");
        Касса.operatorLogin();
        
        // 4. Открытие чека (Тип чека: 1 - Приход, 2 - Возврат прихода)
        Касса.setParam(Касса.LIBFPTR_PARAM_RECEIPT_TYPE, Касса.LIBFPTR_RT_SELL);
        Касса.openReceipt();
        
        // 5. Цикл по табличной части документа 1С
        Для Каждого СтрокаТовара Из Товары Цикл
            
            // Расчет чистой цены без копеечных погрешностей
            КонечнаяЦена = Окр(СтрокаТовара.Сумма / СтрокаТовара.Количество, 2);
            СуммаСтроки = КонечнаяЦена * СтрокаТовара.Количество;
            
            // Регистрация позиции номенклатуры
            Касса.setParam(Касса.LIBFPTR_PARAM_COMMODITY_NAME, СтрокаТовара.Номенклатура.Наименование);
            Касса.setParam(Касса.LIBFPTR_PARAM_PRICE, КонечнаяЦена);
            Касса.setParam(Касса.LIBFPTR_PARAM_QUANTITY, СтрокаТовара.Количество);
            Касса.setParam(Касса.LIBFPTR_PARAM_POSITION_SUM, СуммаСтроки);
            
            // Настройка ставки НДС (например, Без НДС - LIBFPTR_TAX_NO)
            Касса.setParam(Касса.LIBFPTR_PARAM_TAX_TYPE, Касса.LIBFPTR_TAX_NO);
            
            // Регистрация продажи позиции
            Касса.registration();
            
        КонецЦикла;
        
        // 6. Регистрация оплаты (Тип оплаты: 1 - Электронные/Карта, 0 - Наличные)
        // В примере регистрируем оплату наличными на общую сумму документа
        Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_TYPE, Касса.LIBFPTR_PT_CASH);
        Касса.setParam(Касса.LIBFPTR_PARAM_PAYMENT_SUM, Итог("Сумма"));
        Касса.payment();
        
        // 7. Закрытие чека
        Касса.closeReceipt();
        
        Сообщить("Чек успешно пробит на ККТ!");
        
    Исключение
        // В случае ошибки отменяем документ на кассе, чтобы не заблокировать ФН
        Касса.cancelReceipt();
        Сообщить("Произошла ошибка при печати чека: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    КонецПопытки;
    
    // Закрываем соединение с устройством
    Касса.close();

КонецПроцедуры

Используя данный подход, вы сможете гарантировать стабильное пробитие чеков на любой современной кассе АТОЛ напрямую из «1С:Управление торговлей 10.2», полностью контролируя процесс передачи данных и исключая влияние устаревших системных библиотек конфигурации.

← На главную