При разработке нетиповых конфигураций или функционала часто возникает задача: вывести этикетку на термопринтер (например, Zebra) напрямую по нажатию кнопки, минуя промежуточные диалоговые окна и не используя Библиотеку Подключаемого Оборудования (БПО). Мы задаем в коде ИмяПринтера, настраиваем размер страницы и вызываем Напечатать(), но документ упорно уходит на обычный офисный принтер, установленный по умолчанию.
Давайте разберем по шагам, почему возникает эта проблема, и рассмотрим несколько надежных способов ее решения, создавая идеальные условия для прямой печати.
Метод Напечатать() у объекта ТабличныйДокумент молча отправляет задание на принтер по умолчанию, если система не находит устройство с абсолютно точным совпадением переданного имени. Если мы пишем:
ТабДок.ИмяПринтера = "Zebra";
ТабДок.РазмерСтраницы = "Custom";
ТабДок.ВысотаСтраницы = 25;
ТабДок.ШиринаСтраницы = 44;
ТабДок.Напечатать();
Кажется, что все верно. Но чаще всего при работе через удаленный рабочий стол (RDP) Windows пробрасывает принтер в сеанс пользователя и меняет его имя, добавляя номер сессии (например, «Zebra (перенаправлено 62)»). При каждом новом входе эта цифра меняется, точное совпадение пропадает, и 1С игнорирует настройку.
Как это исправить:
Пример правильного указания имени:
ТабДок.ИмяПринтера = "\\ИмяКомпьютера\Zebra";
Альтернативный подход — динамически получать список установленных принтеров через COM-объект WScript.Network (метод EnumPrinterConnections) и программно искать в нем принтер, содержащий подстроку «Zebra», чтобы подставить его актуальное системное имя.
Если мы продолжаем использовать ТабличныйДокумент для генерации этикеток, то указания кастомных высоты и ширины недостаточно. Для термопринтеров критически важно жестко обнулять системные отступы. Если этого не сделать, 1С решит, что макет не помещается на узкой ленте, и начнет печатать криво, со смещением или вообще будет выдавать пустые листы.
Рассмотрим дополненный код, который готовит документ к корректной печати:
ТабДок = Новый ТабличныйДокумент;
// ... заполнение макета ...
ТабДок.ИмяПринтера = "\\Сервер\Zebra";
ТабДок.РазмерСтраницы = "Custom";
ТабДок.ВысотаСтраницы = 25;
ТабДок.ШиринаСтраницы = 44;
// Обязательное обнуление отступов
ТабДок.ПолеСверху = 0;
ТабДок.ПолеСнизу = 0;
ТабДок.ПолеСлева = 0;
ТабДок.ПолеСправа = 0;
ТабДок.РазмерКолонтитулаСверху = 0;
ТабДок.РазмерКолонтитулаСнизу = 0;
ТабДок.АвтоМасштаб = Истина; // Помогает вписать макет в заданную область
ТабДок.Напечатать();
На форуме часто советуют использовать свойство ИмяПараметровПечати. Это своеобразный ключ, по которому 1С запоминает пользовательские настройки печати (выбранный принтер, масштаб, поля) для конкретного документа или обработки.
Однако с этим свойством нужно быть осторожным. Если вы ранее экспериментировали и отправили документ на принтер по умолчанию, 1С могла сохранить этот неудачный выбор в системном кэше (ХранилищеСистемныхНастроек). В итоге, даже если вы жестко прописываете имя в коде, система может подтягивать кэшированные данные. В таком случае поможет очистка настроек печати пользователя в базе или удаление локального кэша.
Многие разработчики, столкнувшись с капризами спулера Windows и масштабирования 1С, полностью отказываются от объекта ТабличныйДокумент при работе с термопринтерами Zebra. Вместо этого используется печать напрямую на родном языке принтера — ZPL или EPL.
Посмотрим на алгоритм этого решения:
%ШтрихКод%.СтрЗаменить для подстановки реальных данных из базы.WScript.Shell скрытой командой copy /b file.txt \\ИмяПК\Zebra, либо через TCP-сокет, если принтер сетевой).Этот подход не требует БПО, работает мгновенно без зависаний, гарантирует идеальную резкость штрихкодов и полностью исключает влияние настроек драйверов Windows.
Наконец, проанализируем контекст выполнения. Убедитесь, что формирование документа и вызов метода Напечатать() происходят исключительно в контексте &НаКлиенте.
Если вы попытаетесь выполнить метод на стороне сервера (например, в фоновом задании), система не сможет получить доступ к пользовательскому интерфейсу Windows и службе спулера. Печать либо упадет с ошибкой, либо документ будет передан на локальный принтер самого сервера, а не пользователя. Все манипуляции с интерфейсом печати должны происходить на клиенте.