Почему драйвер ККТ Штрих-М медленно печатает строки через StringForPrinting и как ускорить печать из 1С

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

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

Разберем детально, как устроена работа драйвера ККТ с текстом, почему нельзя отправить массив строк одной командой через свойство StringForPrinting и как оптимизировать параметры подключения оборудования для непрерывной и плавной печати.

Архитектура свойства StringForPrinting и метода PrintString

Рассмотрим частую ошибку, возникающую при попытке передать несколько строк в драйвер перед отправкой на печать. Начинающие разработчики часто пытаются накопить строки в цикле следующим образом:


// Ошибочный подход — попытка накопления строк в свойстве
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    ДрайверККМ.StringForPrinting = ТЗ.Строка;
КонецЦикла;
ДрайверККМ.PrintString();

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

  1. Свойство StringForPrinting — это обычная строковая переменная в памяти COM-объекта драйвера, а не массив, список или очередь. При каждом присвоении новое значение полностью перезаписывает предыдущее.
  2. Метод PrintString формирует низкоуровневый бинарный пакет команды протокола ККТ (код команды 12H — «Печать строки») и отправляет его непосредственно в кассовый аппарат.
  3. Попытка объединить все строки в одну длинную строку с разделителями перевода каретки (CR/LF) также не даст нужного результата. Максимальная длина поля StringForPrinting ограничена драйвером (до 249 символов), однако кассовый аппарат без включенного автопереноса напечатает только первые 36–56 символов (в зависимости от ширины ленты 57 мм или 80 мм), а остальную часть строки просто обрежет.

Таким образом, базовый алгоритм вывода произвольного нефискального текста всегда строится по схеме: одна строка — одна команда PrintString:


// Корректная последовательность вызова команд
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    ДрайверККМ.StringForPrinting = ТЗ.Строка;
    ДрайверККМ.PrintString();
КонецЦикла;

Почему касса печатает текст с паузами и рывками

Проанализируем механику работы принтера чеков при выполнении единичной команды печати строки. Когда в кассовый аппарат поступает вызов PrintString, микроконтроллер ККТ выполняет следующий цикл операций:

  1. Прием и валидация входящего бинарного пакета из порта.
  2. Запуск шагового двигателя протяжки ленты и подача импульса на термоголовку.
  3. Печать одной физической строки текста.
  4. Остановка шагового двигателя, если в буфере ККТ нет следующей готовой команды.
  5. Отправка байта подтверждения (ACK) обратно в драйвер на компьютере.

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

Основными причинами таких задержек являются:

  1. Низкая скорость физического интерфейса COM-порта (RS-232): Если касса подключена через стандартный COM-порт со скоростью по умолчанию 4800, 9600 или 19200 бит/с, накладные расходы на передачу пакетов и ожидание подтверждения составляют от 50 до 150 мс на каждую строку.
  2. Искусственные задержки в коде 1С: Использование устаревших методов ожидания окончания печати WaitForPrinting и свойств задержки WaitForPrintingDelay.
  3. Повторная установка неизменных свойств: Избыточная перезапись свойств шрифта, выбора ленты (UseReceiptRibbon) и паролей перед каждой строкой внутри цикла.

Пошаговое устранение проблемы медленной печати

Разберем комплекс практических шагов, позволяющих добиться максимальной скорости вывода нефискальных документов на ККТ «Штрих-М».

1. Оптимизация интерфейса подключения и скорости обмена

Главным фактором высокой скорости печати является пропускная способность канала связи между ПК и ККТ:

  1. Переход на USB-подключение: При работе по USB (в режиме виртуального COM-порта или RNDIS) задержки передачи команд сводятся к долям миллисекунды. Буфер кассы успевает наполняться непрерывно, и принтер печатает текст сплошным потоком без остановок.
  2. Повышение скорости RS-232: Если подключение возможно только через физический порт COM (RS-232), необходимо через «Тест драйвера ККТ» открыть Таблицу 1 («Тип и режим кассы»), найти поле «Скорость обмена» и переключить скорость на максимальное поддерживаемое значение — 115200 бит/с. Аналогичную скорость требуется установить в параметрах COM-порта в Диспетчере устройств Windows и в настройках драйвера в 1С.

2. Очистка программного кода от избыточных инструкций

Посмотрим на пример кода, содержащий распространенные избыточные вызовы, замедляющие работу скрипта:


// Пример неоптимального кода с лишними задержками
FR.WaitForPrintingDelay = 100;
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    FR.StringForPrinting = ТЗ.Строка;
    FR.UseReceiptRibbon = 1;      // Лишнее: свойство не меняется
    FR.PrintString();
    FR.WaitForPrinting();        // Лишнее: принудительная заморозка потока 1С
КонецЦикла;

В современных версиях драйвера «Штрих-М» (начиная с 4.x и 5.x) вызовы синхронизированы на уровне самого драйвера, поэтому ручные вызовы WaitForPrinting не требуются. Оптимизированный блок кода должен выглядеть следующим образом:


// Пример оптимизированного алгоритма печати нефискального документа в 1С 7.7
ДрайверККТ.UseReceiptRibbon = 1; // Устанавливаем признак печати на чековой ленте один раз
ДрайверККТ.UseJournalRibbon = 0; // Отключаем контрольную ленту, если она не используется

Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    ПечатаемаяСтрока = СокрЛП(ТЗ.Строка);
    
    // Проверяем длину строки под ширину ленты (например, 36 символов для 57 мм)
    Если СтрДлина(ПечатаемаяСтрока) > 36 Тогда
        ПечатаемаяСтрока = Лев(ПечатаемаяСтрока, 36);
    КонецЕсли;
    
    ДрайверККТ.StringForPrinting = ПечатаемаяСтрока;
    ДрайверККТ.PrintString();
КонецЦикла;

// Отрезка ленты после завершения документа
ДрайверККТ.CutType = 1; // Полная или частичная отрезка
ДрайверККТ.CutCheck();

3. Настройка буферизации чеков в Таблице 1 ККТ

Если печать строк осуществляется внутри открытого чека продажи или сервисного чека, можно задействовать аппаратную буферизацию. В утилите «Тест драйвера ККТ» проверим параметры в Таблице 1:

  1. Поле 19 («Сохранять строки в буфере чека»): Устанавливаем значение 1. Все команды PrintString, PrintWideString и PrintStringWithFont будут помещаться во внутреннюю память кассы без немедленного вывода на ленту.
  2. Поле 20 («Печать чека по закрытию»): Устанавливаем значение 1. Вся печать будет выполнена единым непрерывным блоком в момент вызова метода закрытия чека CloseCheck.
  3. Поле 32 («Разгон при печати»): Устанавливаем значение 1 для включения максимальной скорости протяжки бумаги печатающим механизмом.

Важное замечание: Механизм буферизации чека работает только между операциями OpenCheck (или открытием нефискального документа) и CloseCheck. Если строки отправляются на ленту вне открытого документа, ККТ выводит их немедленно по мере поступления, и решающую роль здесь играет именно скорость интерфейса передачи данных (USB или COM 115200 бод).

← На главную