Разработка собственной конфигурации «с нуля» для небольшого торгового объекта — отличный способ получить максимально быстрое решение без избыточного функционала типовых систем. Однако при реализации розничной торговли разработчики часто сталкиваются с проблемой интеграции торгового оборудования (ТО) в конфигурациях на обычных формах (ОФ). Особую сложность вызывают бюджетные китайские сканеры штрихкодов без предустановленных суффиксов и принтеры чеков.
В этой статье мы подробно разберем, как спроектировать надежную архитектуру взаимодействия с торговым оборудованием в самописной базе 1С, как обойти ограничения «клавиатурных» сканеров штрихкода и как настроить печать чеков без использования дорогостоящих фискальных регистраторов.
---
Перед тем как писать программный код, нам необходимо определиться с архитектурным фундаментом подсистемы торгового оборудования. Существует два основных пути решения этой задачи в конфигурациях на обычных формах:
ТорговоеОборудование и внешних обработок обслуживания (файлы формата *.epf). Достаточно скопировать структуру метаданных, регистры настроек и модули работы с внешними компонентами в свою конфигурацию.Если перед нами стоит задача сделать все максимально просто, быстро и без лишней зависимости от сложных библиотек, рассмотрим варианты прямой реализации работы со сканером и принтером чеков.
---
Самая частая проблема недорогих сканеров — работа в режиме эмуляции клавиатуры (USB-HID). При сканировании прибор просто эмулирует быстрое нажатие клавиш на клавиатуре в активное текстовое поле. В этом случае предопределенное событие платформы 1С ОбработкаВнешнегоСобытия() не вызывается, что делает невозможным автоматическое добавление товара в корзину, если курсор не установлен в специальное поле ввода штрихкода.
Рассмотрим три способа решения этой проблемы по шагам.
Стандартная внешняя компонента «1С:Сканер штрихкода» (библиотека ScanOPOS.dll) умеет перехватывать поток символов от клавиатуры. Она отслеживает интервал времени между нажатиями клавиш. Если символы поступают со скоростью, физически невозможной для человека (таймаут менее 50–100 мс), компонента идентифицирует этот ввод как сканирование, блокирует передачу символов в активное поле ввода операционной системы и генерирует штатное внешнее событие в 1С.
При этом настраивать префиксы и суффиксы в самом сканере штрихкода не требуется. В настройках драйвера 1С в поле «Порт» необходимо выбрать значение «Клавиатура».
Для того чтобы форма документа или кассира реагировала на сканирование, в модуле формы необходимо прописать следующий код:
Процедура ПриОткрытии()
// Включаем обработку внешних событий от торгового оборудования
ПолучитьФорму().ЗанятьПортЭксклюзивно = Истина;
КонецПроцедуры
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
// Проверяем, что событие пришло от сканера штрихкодов
Если Найти(ВРег(Событие), "BARCODE") > 0 Или Найти(ВРег(Событие), "ШТРИХКОД") > 0 Тогда
Штрихкод = СокрЛП(Данные);
// Вызываем функцию обработки найденного штрихкода
ОбработатьСканированиеШтрихкода(Штрихкод);
КонецЕсли;
КонецПроцедуры
Если стандартный драйвер 1С работает нестабильно, отличным решением станет старый бесплатный драйвер устройств ввода от компании АТОЛ версии 6.x. Он также прекрасно перехватывает клавиатурный ввод и передает его в виде внешнего события 1С. Достаточно установить драйвер в операционную систему и подключить соответствующую внешнюю компоненту в коде 1С.
Это самый надежный технический вариант. Даже безымянные китайские сканеры штрихкода чаще всего аппаратно поддерживают эмуляцию COM-порта через интерфейс USB. Чтобы перевести устройство в этот режим:
ОбработкаВнешнегоСобытия без каких-либо клавиатурных хуков и зависаний фокуса.---
Если торговая точка работает по системе ЕНВД (патентная система налогообложения) и не обязана в режиме реального времени отправлять данные о продажах через ОФД в налоговую службу, для печати чеков покупателям можно использовать обычный чековый принтер (принтер чеков шириной 58 мм или 80 мм). Проанализируем два способа вывода чеков на печать.
Этот способ является наиболее простым и гибким в плане верстки чека. Мы создаем стандартный макет табличного документа в конфигурации, настраиваем его дизайн (шрифты, границы, логотип магазина) и выводим на печать средствами платформы 1С.
Разберем по шагам код программного вывода табличного документа на принтер чеков без вызова диалогового окна выбора принтера:
Процедура НапечататьЧекНаПринтереWindows(ДокументСсылка)
ТабДок = Новый ТабличныйДокумент;
// Задаем уникальное имя параметров печати, чтобы настройки сохранялись индивидуально
ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ЧЕКА_58ММ";
// Получаем макет чека из метаданных нашей обработки или документа
Макет = ПолучитьМакет("МакетЧека58мм");
// Заполняем и выводим область Шапка
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Организация = "ИП Иванов И.И.";
ОбластьШапка.Параметры.НомерДокумента = ДокументСсылка.Номер;
ОбластьШапка.Параметры.ДатаДокумента = Формат(ДокументСсылка.Дата, "ДФ='dd.MM.yyyy HH:mm'");
ТабДок.Вывести(ОбластьШапка);
// Заполняем и выводим строки табличной части документа
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
ОбластьСтрока.Параметры.Товар = СтрокаТЧ.Номенклатура.Наименование;
ОбластьСтрока.Параметры.Количество = СтрокаТЧ.Количество;
ОбластьСтрока.Параметры.Цена = СтрокаТЧ.Цена;
ОбластьСтрока.Параметры.Сумма = СтрокаТЧ.Сумма;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
// Заполняем и выводим Итоги чека
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ОбластьПодвал.Параметры.Всего = ДокументСсылка.СуммаДокумента;
ТабДок.Вывести(ОбластьПодвал);
// Задаем настройки страницы под чековую ленту шириной 58 мм
ТабДок.АвтоМасштаб = Истина;
ТабДок.ИмяПринтера = "XP-58"; // Имя принтера, как оно задано в панели управления Windows
// Обнуляем поля табличного документа, чтобы текст не обрезался по краям ленты
ТабДок.Поля.Лево = 0;
ТабДок.Поля.Право = 0;
ТабДок.Поля.Верх = 0;
ТабДок.Поля.Низ = 0;
// Отправляем на принтер напрямую (без вывода окна диалога печати)
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры
Если принтер подключен напрямую к COM-порту (или USB-кабелем с эмуляцией COM-интерфейса), мы можем обойтись без драйверов принтера в Windows. Печать происходит путем отправки текстовых строк напрямую в COM-порт принтера. Этот способ обеспечивает молниеносную печать и позволяет отправлять специальные управляющие команды принтеру (например, звуковой сигнал встроенного зуммера, автоотрезчик чека или команда открытия денежного ящика).
Для отправки данных в COM-порт мы воспользуемся стандартным объектом платформы 1С ЗаписьТекста, указав имя COM-порта в качестве пути к файлу:
Процедура ОтправитьЧекНаESC_POS(ИмяПорта, ДокументСсылка)
// ИмяПорта передается как "COM3" или сетевой путь к принтеру "\\localhost\XP-80"
ТекстЧека = Новый ЗаписьТекста;
Попытка
ТекстЧека.Открыть(ИмяПорта, КодировкаТекста.OEM); // Используем кодировку DOS (OEM/CP866)
Исключение
Предупреждение("Не удалось открыть порт принтера чеков! Проверьте подключение.");
Возврат;
КонецПопытки;
// Команда ESC @ — Инициализация принтера (сброс настроек)
ТекстЧека.ЗаписатьСтроку(Символ(27) + Символ(64));
// Команда ESC a 1 — Выравнивание текста по центру
ТекстЧека.ЗаписатьСтроку(Символ(27) + Символ(97) + Символ(1));
ТекстЧека.ЗаписатьСтроку("МАГАЗИН ПРОДУКТОВ");
ТекстЧека.ЗаписатьСтроку("Добро пожаловать!");
ТекстЧека.ЗаписатьСтроку("ЧЕК ПРОДАЖИ № " + ДокументСсылка.Номер);
ТекстЧека.ЗаписатьСтроку("================================");
// Команда ESC a 0 — Выравнивание текста по левому краю
ТекстЧека.ЗаписатьСтроку(Символ(27) + Символ(97) + Символ(0));
// Выводим строки товаров
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
Наименование = Лев(СтрокаТЧ.Номенклатура.Наименование, 20);
СуммаСтр = Формат(СтрокаТЧ.Сумма, "ЧЦ=10; ЧДЦ=2");
// Форматируем строку, дополняя пробелами до ширины ленты
КоличествоПробелов = 32 - СтрДлина(Наименование) - СтрДлина(СуммаСтр);
Пробелы = "";
Для Шаг = 1 По КоличествоПробелов Цикл
Пробелы = Пробелы + " ";
КонецЦикла;
ТекстЧека.ЗаписатьСтроку(Наименование + Пробелы + СуммаСтр);
КонецЦикла;
ТекстЧека.ЗаписатьСтроку("================================");
// Выводим Итог
ИтогСтрока = "ИТОГО: " + Формат(ДокументСсылка.СуммаДокумента, "ЧЦ=10; ЧДЦ=2");
ТекстЧека.ЗаписатьСтроку(ИтогСтрока);
// Протяжка ленты на 3 строки вперед, чтобы чек вышел из принтера
ТекстЧека.ЗаписатьСтроку(Символ(10) + Символ(10) + Символ(10));
// Команда GS V 66 0 — Частичная отрезка бумаги автоотрезчиком принтера
ТекстЧека.ЗаписатьСтроку(Символ(29) + Символ(86) + Символ(66) + Символ(0));
// Закрываем порт
ТекстЧека.Закрыть();
КонецПроцедуры
---
Мы проанализировали основные нюансы работы с торговым оборудованием в самописных базах 1С на обычных формах. Написание собственной системы поддержки сканера и принтера чеков не требует колоссальных трудозатрат, если правильно подойти к выбору режимов работы устройств.
Для гарантированной работы сканера штрихкодов переводите прибор в режим виртуального COM-порта или используйте таймаут-перехватчик клавиатуры в компоненте ScanOPOS. При настройке печати чеков оценивайте требования заказчика: если важен красивый внешний вид чека с логотипом — верстайте его через стандартный табличный макет 1С; если критична скорость печати и автоматическая работа отрезчика чековой ленты — используйте прямые ESC/POS команды.