При работе в платформе 1С 7.7 в терминальном режиме (например, на Windows Server) часто возникает задача отправки документов на разные сетевые принтеры в зависимости от реквизитов документа или логики бизнес-процесса. Однако стандартный метод ПараметрыСтраницы() с указанием имени устройства в 12-м параметре может работать нестабильно и отправлять задание на последне отпечатанный принтер или принтер по умолчанию.
Разберем основные причины такого поведения платформы и проанализируем рабочие способы решения этой проблемы.
Рассмотрим, почему 1С 7.7 может игнорировать переданное в коде имя устройства:
HKCU\Software\1C\1Cv7\7.7\<База>\V7\<Пользователь>\Moxel. Если для формы используется один и тот же ключ в методе Опции(), 1C 7.7 считывает сохраненное ранее имя принтера из реестра и переопределяет переданное значение.ПараметрыСтраницы() корректно воспринимает сетевое имя устройства только в том случае, если длина строки (включая имя сервера) не превышает 31–32 символов.Чтобы платформенный кэш не подставлял предыдущие настройки принтера, необходимо вызывать Опции() и ПараметрыСтраницы() строго парой, причем в 5-й параметр метода Опции() передавать уникальный идентификатор (например, с добавлением имени принтера или вида печатной формы).
Рассмотрим пример кода:
// Формируем уникальный ключ опций печати для каждого принтера
ИмяТекущийПринтер = "Har_Sklad";
Таб.Опции(0, 0, 0, 0, "ОпцииПечати_Реализация_" + ИмяТекущийПринтер);
Таб.ПараметрыСтраницы(1, , , , , , , , , 1, 1, ИмяТекущийПринтер);
Таб.Напечатать(0);
Если direct-указание устройства в ПараметрыСтраницы() все равно приводит к сбоям, наиболее надежным решением является временная смена системного принтера по умолчанию перед отправкой документа на печать с помощью COM-объекта WScript.Network.
Пошагово разберем этот алгоритм:
EnumPrinterConnections().SetDefaultPrinter().Напечатать(0).Проанализируем пример получения списка доступных принтеров в текущем терминальном сеансе:
N = СоздатьОбъект("WScript.Network");
NetworkPrinters = N.EnumPrinterConnections();
Для Сч = 0 По NetworkPrinters.length - 1 Цикл
Сообщить("Подключен сетевой принтер " + NetworkPrinters.Item(Сч) + " [" + NetworkPrinters.Item(Сч + 1) + "]");
Сч = Сч + 1;
КонецЦикла;
После того как точные имена принтеров определены, реализуем итоговый рабочий алгоритм печати:
Тз = СоздатьОбъект("ТаблицаЗначений");
Тз.НоваяКолонка("Итем");
Тз.НоваяКолонка("Имя");
N = СоздатьОбъект("WScript.Network");
NetworkPrinters = N.EnumPrinterConnections();
Для Сч = 0 По NetworkPrinters.length - 1 Цикл
Тз.НоваяСтрока();
Тз.Итем = NetworkPrinters.Item(Сч + 1);
Тз.Имя = СокрЛП(Строка(NetworkPrinters.Item(Сч + 1)));
Сч = Сч + 1;
КонецЦикла;
PrinterDef = "";
PrinterPrint = "";
Тз.ВыбратьСтроки();
Пока Тз.ПолучитьСтроку() = 1 Цикл
Если Тз.Имя = "FS-C5150DN" Тогда
PrinterDef = Тз.Итем;
КонецЕсли;
Если Тз.Имя = "OSn_Sklad" Тогда
PrinterPrint = Тз.Итем;
КонецЕсли;
КонецЦикла;
// Печать на первый принтер
Т1 = СоздатьОбъект("Таблица");
Т1.ВывестиСекцию("Шапка");
N.SetDefaultPrinter(PrinterPrint);
Т1.ПараметрыСтраницы(1, , , , , , , , , 1, , PrinterPrint);
Т1.Напечатать(0);
// Печать на второй принтер
Т2 = СоздатьОбъект("Таблица");
Т2.ВывестиСекцию("Шапка");
N.SetDefaultPrinter(PrinterDef);
Т2.ПараметрыСтраницы(1, , , , , , , , , 1, , PrinterDef);
Т2.Напечатать(0);
Для предотвращения сбоев при печати из 1С 7.7 на серверах Windows Server соблюдайте следующие правила:
Используйте короткие имена принтеров. Называйте принтеры на сервере латинскими буквами без пробелов и спецсимволов, длиной не более 10–15 символов (например, HarSklad вместо Printer_Hartmann_Department_1).
Избегайте RDP-перенаправления для стационарных принтеров. Если печать выполняется на склады или в офисы, подключайте сетевые принтеры напрямую к серверу как локальные TCP/IP принтеры, чтобы их имена оставались статичными при любом входе пользователя в терминальный сеанс.