Как исправить ошибку Заданный принтер не найден при программной печати в 1С 7.7

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

В процессе разработки в среде 1С:Предприятие 7.7 программисты часто сталкиваются с задачей автоматического выбора принтера для конкретных документов — например, для печати чеков на специализированный принтер или отчетов на сетевое устройство. Одной из самых коварных ошибок при использовании метода ИмяПринтера объекта ПараметрыПечати является сообщение «заданный принтер не найден», даже если название принтера кажется абсолютно верным. В этой статье мы подробно разберем причины этой проблемы, изучим архитектурные особенности хранения данных в 1С 7.7 и предложим надежные варианты решения.

Причина ошибки: коварные пробелы и фиксированная длина строк

Проанализируем ситуацию: разработчик выбирает принтер из системного списка, обрезает лишние пробелы функцией СокрЛП() и записывает результат в константу. Однако при последующем чтении из этой константы 1С выдает ошибку. Выясним, почему это происходит.

Дело в том, что архитектура 1С 7.7 (вне зависимости от того, используется ли DBF-версия или SQL-вариант) работает со строками фиксированной длины. Если в конфигураторе для константы задана длина, например, 50 символов, то любое значение, которое вы туда записываете, будет автоматически дополнено пробелами справа до этих самых 50 символов.

Рассмотрим пример. Допустим, ваш принтер называется HP LaserJet (11 символов). Вы записываете его в константу:


// Казалось бы, здесь мы все почистили
константа.принтерЧеков = СокрЛП(принтерЧеков); 

Однако в базе данных это значение будет храниться как "HP LaserJet ". При последующем обращении к методу Таб.ПараметрыПечати.ИмяПринтера система получает строку именно в таком виде — с десятками невидимых пробелов на конце. Поскольку в операционной системе Windows принтер зарегистрирован под строгим именем без лишних хвостов, 1С закономерно сообщает, что устройство не найдено.

Решение проблемы через правильное чтение данных

Для исправления ситуации необходимо применять функцию СокрЛП() не только при записи значения, но и — что критически важно — непосредственно при его чтении из базы данных перед использованием. Перейдем к правильному коду формирования отчета:


Процедура ЗамутитьОтчет()
    // Формируем таблицу...
    Таб = СоздатьОбъект("ТабличныйДокумент");
    // ... заполнение таблицы ...
    
    // ПРАВИЛЬНЫЙ ВАРИАНТ:
    // Обязательно обрезаем пробелы, которые 1С добавила при хранении в константе
    Таб.ПараметрыПечати.Ориентация = 1;
    Таб.ПараметрыПечати.ИмяПринтера = СокрЛП(Константа.принтерЧеков);
    
    Таб.Напечатать(0); // Печать без диалога
КонецПроцедуры

Посмотрим на разницу: в исходном коде автора использовалось прямое обращение Константа.принтерЧеков, что и приводило к передаче "хвоста" из пробелов. Использование СокрЛП() при обращении гарантирует, что в метод ИмяПринтера попадет только значимое название.

Как корректно получить список принтеров в системе

Рассмотрим, как можно автоматизировать выбор принтера пользователем, чтобы не заставлять его вводить имя вручную. В 1С 7.7 нет встроенного метода для получения списка установленных принтеров, поэтому часто используются возможности Windows Script Host (WSH).

Разберем процедуру получения списка принтеров:


Процедура ПриОткрытии()
    Попытка
        WshNetwork = СоздатьОбъект("WScript.Network");
        Printers = WshNetwork.EnumPrinterConnections();
        
        СписокПринтеров = СоздатьОбъект("СписокЗначений");
        // В коллекции WSH принтеры идут парами: [Индекс+1] - Порт, [Индекс+2] - Имя
        Н = 0;
        Пока Н <= Printers.Count() - 1 Цикл
            СписокПринтеров.ДобавитьЗначение(Printers.Item(Н + 1));
            Н = Н + 2;
        КонецЦикла;
        
        // Выгружаем в таблицу на форме для выбора
        СписокПринтеров.Выгрузить(табПринт);
    Исключение
        Предупреждение("Не удалось получить список принтеров через WScript!");
    КонецПопытки;
КонецПроцедуры

Обратите внимание, что объект WScript.Network возвращает коллекцию, где элементы чередуются: локальный порт или сетевой путь, а затем дружественное имя принтера. Именно поэтому шаг цикла в примере равен 2.

Альтернативный способ: Использование внешней компоненты FormEx

Для тех, кто хочет избежать работы с медленным WSH или COM-объектами, существует более профессиональный путь — использование внешней компоненты FormEx. Она позволяет получить список принтеров одной командой и предоставляет более стабильный доступ к сервисным функциям системы.

Пример использования FormEx для получения списка:


// Если компонента загружена
Сервис = СоздатьОбъект("Сервис");
Список = Сервис.ПолучитьСписокПринтеров();
// Список теперь содержит все доступные принтеры

Метод Сервис.Принтер() также позволяет мгновенно переключать активный принтер в рамках сессии 1С, что бывает крайне полезно при работе с чековыми принтерами и этикетками.

Дополнительные факторы, влияющие на поиск принтера

Если даже после применения СокрЛП() принтер не находится, проанализируем дополнительные внешние факторы, которые часто встречаются в современных системах (Windows 10/11) и при работе в терминальном режиме.

1. Терминальные (RDP) принтеры

Если ваша 1С работает на сервере через удаленный рабочий стол, имена принтеров могут динамически меняться. Например, принтер может называться HP LaserJet (from session 12). При следующем входе номер сессии изменится, и имя, сохраненное в константе, станет недействительным. В таких случаях рекомендуется:

2. Настройка Windows 10 «Управление принтером по умолчанию»

Современные версии Windows любят самостоятельно менять принтер по умолчанию на тот, который использовался последним. Это может конфликтовать с логикой 1С. Рекомендуется зайти в Параметры -> Устройства -> Принтеры и сканеры и снять галочку с пункта «Разрешить Windows управлять принтером, используемым по умолчанию».

3. Кэширование настроек в макете (.mxl)

Иногда настройки принтера «зашиваются» внутри самого макета отчета. Если отчет упорно пытается печатать не туда или выдает ошибки, попробуйте открыть макет в конфигураторе, перейти в меню Файл — Параметры страницы, нажать ОК (ничего не меняя) и сохранить макет. Это сбросит привязку к старому драйверу, который мог быть удален из системы.

Итоги

Подведем итог нашему исследованию. Ошибка «заданный принтер не найден» в 90% случаев в 1С 7.7 лечится простым добавлением СокрЛП() в момент передачи имени принтера в объект ТабличныйДокумент. Остальные 10% приходятся на специфику работы RDP-сессий и прав доступа к сетевым принтерам. Всегда проверяйте, что имя принтера в базе данных в точности соответствует тому, что вы видите в панели управления Windows, и не забывайте про технические ограничения платформы при работе со строками.

← На главную