Проблема с печатью на чековые принтеры в терминальной сессии (RDP) — это классическая ситуация, с которой сталкиваются многие разработчики при работе с обычными формами 1С:Предприятие 8.3. Ситуация часто выглядит так: принтер виден в системе, программный код находит его имя, команда Напечатать() выполняется без ошибок, но в очереди печати ничего не появляется. При этом, если вывести документ на экран и выбрать тот же принтер вручную, всё работает корректно. Разберем подробно причины этого поведения и способы решения задачи.
Первая и самая очевидная причина кроется в динамическом изменении имен принтеров. Когда пользователь подключается по RDP, его локальный принтер пробрасывается на сервер с суффиксом, например: (перенаправлено 5) или (redirected 2). Номер сессии меняется при каждом новом подключении. Рассмотрим, почему это критично для 1С.
Если в коде или в настройках макета (файл параметров печати пользователя) сохранено старое имя принтера, 1С будет пытаться отправить задание на несуществующий объект. Даже если вы используете WSHNetwork.EnumPrinterConnections() для поиска актуального имени, платформа может игнорировать программную установку, если в самом табличном документе уже "зашито" имя из предыдущей сессии.
Проанализируем ситуацию: метод ТабличныйДокумент.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать) крайне чувствителен к точному соответствию имени принтера в реестре Windows сервера. Чтобы избежать ошибок, перед печатью необходимо принудительно очищать настройки и задавать имя программно.
ТабДок = Новый ТабличныйДокумент;
// ... формирование документа ...
ТабДок.ИмяПринтера = НужноеИмяПринтера;
ТабДок.ПараметрыСтраницы.ИмяПринтера = НужноеИмяПринтера;
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
Одной из главных скрытых причин проблем с чековыми (POS) принтерами является технология Easy Print. По умолчанию Windows пытается использовать универсальный драйвер для всех проброшенных устройств. Это удобно для офисных принтеров, но губительно для чековых лент, так как универсальный драйвер не понимает специфических команд (обрезка, управление денежным ящиком) и может некорректно обрабатывать нестандартные размеры страниц.
Выясним, как это лечится. Необходимо заставить сервер использовать "родной" драйвер принтера, установленный непосредственно на сервере (он должен совпадать с драйвером на локальном ПК). Для этого системному администратору нужно изменить групповые политики (GPO):
Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Перенаправление принтеров.
Здесь нужно установить параметр "Использовать в первую очередь драйвер принтера Easy Print удаленного рабочего стола" в состояние "Отключено".
Посмотрим на пример того, как система возвращает имя принтера. Часто при перечислении через COM-объекты или WMI имя выглядит как ИмяПринтера (перенаправлено 5) на Ne01:. Для метода 1С Напечатать() часть строки, начинающаяся со слова "на" или "on", может быть лишней или приводить к ошибке инициализации задания печати.
Рекомендуется очищать полученную строку. Рассмотрим по шагам, как это сделать:
Функция ОчиститьИмяПринтера(ИсходноеИмя)
Поз = Найти(ИсходноеИмя, " на ");
Если Поз > 0 Тогда
Возврат Лев(ИсходноеИмя, Поз - 1);
КонецЕсли;
Поз = Найти(ИсходноеИмя, " on ");
Если Поз > 0 Тогда
Возврат Лев(ИсходноеИмя, Поз - 1);
КонецЕсли;
Возврат ИсходноеИмя;
КонецФункции
Разберем ситуацию, когда задание создается, но тут же пропадает. Даже если код выполняется "на клиенте", фактически процесс 1cv8.exe работает в контексте вашей RDP-сессии на сервере. Для формирования задания печати пользователю необходимы права на запись в системную директорию C:\Windows\System32\spool\PRINTERS на серверной ОС.
Если прав недостаточно, очередь печати не сможет сформировать временный файл задания. Проверьте права пользователя или попробуйте запустить 1С от имени администратора (для теста), чтобы исключить этот фактор.
Если стандартные методы 1С (Напечатать или Печать) продолжают игнорировать принтер, проанализируем вариант с обходом механизмов платформы. Это наиболее надежный способ для "капризных" китайских драйверов (XPrinter, Zjiang).
Суть метода заключается в сохранении чека во временный файл и отправке его на печать через командную строку операционной системы. Посмотрим на алгоритм:
ТабличныйДокумент в формат PDF или MXL.ЗапуститьПриложение().
ПутьКФайлу = КаталогВременныхФайлов() + "ticket.pdf";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
КомандаПечати = """C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to """ + НужноеИмяПринтера + """ -silent """ + ПутьКФайлу + """";
ЗапуститьПриложение(КомандаПечати, , Истина);
Этот способ позволяет полностью избежать проблем с кэшированием настроек принтера внутри 1С и некорректной передачей параметров страницы через GDI-интерфейс платформы.
В заключение разберем еще один нюанс. 1С сохраняет параметры печати (ориентация, масштаб, имя принтера) для каждого макета в профиле пользователя. Если вы переименовывали принтер или переустанавливали драйвер, старые настройки могут блокировать новые.
Попробуйте следующее:
Удалите содержимое папки %AppData%\1C\1cv8\ (кэш пользователя). При следующем запуске 1С "забудет" старое имя принтера и корректно инициализирует его из кода. Также полезно в самом коде перед печатью устанавливать ТабДок.ПараметрыСтраницы.ИмяПринтера = "", а затем уже присваивать актуальное значение.
Проанализировав все вышеперечисленные факторы — от настроек GPO до программной очистки имен — вы сможете обеспечить стабильную работу чекового принтера в любой терминальной среде.