При интеграции кассовых аппаратов и фискальных регистраторов компании «Штрих-М» с учетными системами 1С разработчики нередко сталкиваются с ситуацией, когда печать стандартного фискального чека продажи происходит моментально, а вывод произвольного нефискального текста (например, слип-чека эквайринга, копии документа, сервисного отчета или товарного чека) занимает неприемлемо много времени. При этом кассовый аппарат издает характерный прерывистый звук («тарахтит как трактор»), протягивая кассовую ленту рывками с паузами между строками.
Разберем детально, как устроена работа драйвера ККТ с текстом, почему нельзя отправить массив строк одной командой через свойство StringForPrinting и как оптимизировать параметры подключения оборудования для непрерывной и плавной печати.
Рассмотрим частую ошибку, возникающую при попытке передать несколько строк в драйвер перед отправкой на печать. Начинающие разработчики часто пытаются накопить строки в цикле следующим образом:
// Ошибочный подход — попытка накопления строк в свойстве
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
ДрайверККМ.StringForPrinting = ТЗ.Строка;
КонецЦикла;
ДрайверККМ.PrintString();
При таком коде кассовый аппарат распечатает исключительно последнюю строку таблицы значений. Выясним причину такого поведения драйвера:
StringForPrinting — это обычная строковая переменная в памяти COM-объекта драйвера, а не массив, список или очередь. При каждом присвоении новое значение полностью перезаписывает предыдущее.PrintString формирует низкоуровневый бинарный пакет команды протокола ККТ (код команды 12H — «Печать строки») и отправляет его непосредственно в кассовый аппарат.StringForPrinting ограничена драйвером (до 249 символов), однако кассовый аппарат без включенного автопереноса напечатает только первые 36–56 символов (в зависимости от ширины ленты 57 мм или 80 мм), а остальную часть строки просто обрежет.Таким образом, базовый алгоритм вывода произвольного нефискального текста всегда строится по схеме: одна строка — одна команда PrintString:
// Корректная последовательность вызова команд
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
ДрайверККМ.StringForPrinting = ТЗ.Строка;
ДрайверККМ.PrintString();
КонецЦикла;
Проанализируем механику работы принтера чеков при выполнении единичной команды печати строки. Когда в кассовый аппарат поступает вызов PrintString, микроконтроллер ККТ выполняет следующий цикл операций:
Если время передачи следующей строки из 1С превышает время, за которое двигатель завершает шаг, принтер останавливает протяжку бумаги. Каждая последующая строка заново разгоняет и останавливает двигатель термоголовки, порождая паузы и сильный шум.
Основными причинами таких задержек являются:
WaitForPrinting и свойств задержки WaitForPrintingDelay.UseReceiptRibbon) и паролей перед каждой строкой внутри цикла.Разберем комплекс практических шагов, позволяющих добиться максимальной скорости вывода нефискальных документов на ККТ «Штрих-М».
Главным фактором высокой скорости печати является пропускная способность канала связи между ПК и ККТ:
Посмотрим на пример кода, содержащий распространенные избыточные вызовы, замедляющие работу скрипта:
// Пример неоптимального кода с лишними задержками
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();
Если печать строк осуществляется внутри открытого чека продажи или сервисного чека, можно задействовать аппаратную буферизацию. В утилите «Тест драйвера ККТ» проверим параметры в Таблице 1:
1. Все команды PrintString, PrintWideString и PrintStringWithFont будут помещаться во внутреннюю память кассы без немедленного вывода на ленту.1. Вся печать будет выполнена единым непрерывным блоком в момент вызова метода закрытия чека CloseCheck.1 для включения максимальной скорости протяжки бумаги печатающим механизмом.Важное замечание: Механизм буферизации чека работает только между операциями OpenCheck (или открытием нефискального документа) и CloseCheck. Если строки отправляются на ленту вне открытого документа, ККТ выводит их немедленно по мере поступления, и решающую роль здесь играет именно скорость интерфейса передачи данных (USB или COM 115200 бод).