Как реализовать печать из 1С 7.7 на термопринтер через Windows Sockets?

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

При автоматизации торговых точек часто возникает задача прямой печати чеков или этикеток на термопринтеры (например, Штрих-600, Дримкас или Zebra) по сети. Использование стандартных драйверов Windows не всегда удобно, так как они могут некорректно масштабировать шрифты или работать медленно. В таких случаях программисты 1С 7.7 прибегают к использованию компоненты MSWinsock.Winsock. Разберем подробно, с какими трудностями можно столкнуться и как их преодолеть.

Проблема асинхронности соединения

Основная ошибка при работе с MSWinsock.Winsock заключается в непонимании асинхронной природы метода Connect. Проанализируем ситуацию: когда мы вызываем команду подключения, программа не ждет установления связи, а сразу переходит к следующей строке кода. Если попытаться отправить данные немедленно, система выдаст ошибку: "Winsock: Wrong protocol or connection state for the requested transaction or request".

Рассмотрим правильный алгоритм инициализации соединения. Нам необходимо дождаться, пока свойство State объекта примет значение 7 (sckConnected). Состояние 6 (sckConnecting) означает, что процесс еще идет.


Драйвер = СоздатьОбъект("MSWinsock.Winsock");
Драйвер.Protocol = 0; // sckTCPProtocol
Драйвер.RemoteHost = "192.168.10.90";
Драйвер.RemotePort = 9100;
Драйвер.Connect();

// Ожидаем установления соединения
Пока (Драйвер.State = 6) Цикл
    // В идеале здесь стоит добавить небольшую паузу, 
    // чтобы не перегружать процессор
КонецЦикла;

Если Драйвер.State <> 7 Тогда
    Сообщить("Не удалось подключиться к принтеру. Статус: " + Драйвер.State);
    Возврат;
КонецЕсли;

Драйвер.SendData(AnsiToOem("Тестовая строка" + РазделительСтрок));

Управление шрифтами и ESC-последовательности

При прямой отправке текста через сокет на порт 9100 (протокол RAW) принтер печатает данные "как есть". Часто это приводит к тому, что текст получается слишком крупным или не помещается на узкой ленте. Для управления внешним видом чека используются ESC/POS команды — специальные непечатные символы, которые принтер интерпретирует как инструкции.

Выясним причину, почему простые строки могут выглядеть некорректно. Принтеры чеков обычно работают в кодировке CP866 (OEM). Поэтому использование функции AnsiToOem() обязательно. Однако для смены шрифта или ширины печати нужно передать управляющий байт Chr(27) (ESC).

Рассмотрим пример кода для настройки печати:


// Сброс настроек принтера (Initialize)
Драйвер.SendData(Chr(27) + "@"); 

// Выбор кодовой страницы (зависит от модели, часто 17 - это PC866)
Драйвер.SendData(Chr(27) + "t" + Chr(17));

// Печать сжатым шрифтом (Font B)
Драйвер.SendData(Chr(27) + "!" + Chr(1)); 
Драйвер.SendData(AnsiToOem("Это очень узкая строка для чека") + Chr(10));

// Печать жирным шрифтом
Драйвер.SendData(Chr(27) + "E" + Chr(1));
Драйвер.SendData(AnsiToOem("ЖИРНЫЙ ТЕКСТ") + Chr(10));
Драйвер.SendData(Chr(27) + "E" + Chr(0)); // Отмена жирного

Альтернативный способ: Настройка через свойства сервера печати

Если работа с сокетами напрямую кажется слишком сложной или нестабильной (например, соединение часто обрывается), можно воспользоваться системными настройками Windows. Проанализируем этот метод, предложенный опытными пользователями:

  1. Установите принтер в системе как Generic / Text Only.
  2. В свойствах сервера печати (в папке "Принтеры и факсы") создайте новый макет бумаги. Укажите фиксированную ширину (например, 10.5 см, что часто является системным минимумом для некоторых драйверов) и необходимую высоту.
  3. В настройках принтера и в параметрах устройства (Device Settings) выберите созданный макет для всех лотков и типов бумаги (например, Roll paper feeder).
  4. В самой 1С 7.7 настройте макет так, чтобы суммарная ширина колонок соответствовала ширине ленты (обычно около 16-20 пунктов в свойствах ячейки).

Этот способ позволяет использовать стандартную команду Таб.Напечатать(0), при этом Windows не будет пытаться превратить текст в графику, а отправит его в поток принтера.

Использование внешних компонент (VK)

Как показывает практика, штатный MSWinsock в среде 1С 7.7 может вести себя капризно, особенно при закрытии сессий. Программисты часто создают свои внешние компоненты (на C# или Delphi), которые оборачивают работу с сокетами в удобные методы. Рассмотрим преимущества такого подхода:

Пример использования гипотетической компоненты:


Штрих = СоздатьОбъект("AddIn.Shtrih600Lib");
// Параметры: IP, Порт, Текст (с поддержкой управляющих последовательностей)
Штрих.Print("192.168.10.90", "9100", ТекстЧека);

Важные замечания по безопасности и сети

Разберем еще один нюанс: современные операционные системы (Windows 10/11) имеют строгие настройки брандмауэра. Если ваш код застревает на State = 6, обязательно проверьте следующее:

  1. Разрешен ли исходящий трафик для процесса 1cv7.exe или 1cv7s.exe.
  2. Доступен ли IP-адрес принтера (проверьте командой ping из консоли).
  3. Не занят ли порт 9100 другим приложением или сессией (многие дешевые принтеры поддерживают только одно активное соединение одновременно).

Подводя итог, можно сказать, что печать через сокеты — это наиболее гибкий способ управления чековым принтером в 1С 7.7, позволяющий использовать все возможности "железа", но требующий аккуратной работы с состояниями объекта Winsock и понимания протокола ESC/POS.

← На главную