При разработке механизмов пакетной печати документов в конфигурациях на обычных формах (например, в «1С:Управление торговлей 10.3» или «1С:Комплексная автоматизация 1.1») разработчики часто сталкиваются с ситуацией, когда типовые печатные формы выводятся без проблем, а внешние печатные формы (ВПФ) прерывают автоматический процесс. Наиболее частый пример — товарно-транспортная накладная (форма 1-Т), которая открывает диалоговое окно для заполнения сведений о перевозчике, водителе или путевом листе.
Разберем причины такого поведения и рассмотрим проверенные способы организовать бесперебойную печать внешних обработок без необходимости ручного нажатия кнопок пользователем.
Посмотрим на классический алгоритм вызова печати через типовой общий модуль УниверсальныеМеханизмы:
ДеревоМакетов = УниверсальныеМеханизмы.ПолучитьДеревоМакетовПечати(Объект.Ссылка, Объект.ПолучитьСтруктуруПечатныхФорм, , );
ИскомоеИмя = "1-Т (Товарно-транспортная накладная) внеш";
СтрМакета = ДеревоМакетов.Строки.Найти(ИскомоеИмя, "Текст");
Расшифровка = СтрМакета.Расшифровка;
Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
ПечДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(Строка.ДокументРеализация, Расшифровка);
УниверсальныеМеханизмы.НапечататьДокумент(ПечДокумент, 2, НаПринтер, ОбщегоНазначения.СформироватьЗаголовокДокумента(Строка.Ссылка), );
Сообщить("Печать внешней формы: " + Строка.ДокументРеализация);
Иначе
Объект.Печать(Расшифровка, 2, НаПринтер);
Сообщить("Печать внутренней формы: " + Строка.ДокументРеализация);
КонецЕсли;
Функция УниверсальныеМеханизмы.НапечататьВнешнююФорму открывает внешнюю обработку и ожидает возврата сформированного табличного документа. Однако, если обработка внутри себя вызывает открытие собственной формы (через метод Форма.Открыть() или Форма.ОткрытьМодально()), выполнение потока останавливается или требует реакции пользователя.
Выясним причину: в отличие от стандартных печатных форм, алгоритм формирования которых полностью расположен в модуле объекта обработки (функция Печать()), во внешних ТТН логика часто вынесена в модуль формы, а заполнение выполняется в обработчиках событий ПриОткрытии() или по нажатию командных кнопок.
Если код внешней печатной формы доступен для редактирования, самым надежным и чистым решением является добавление флага пакетного режима работы.
ПакетныйРежим с типом Булево.Печать() модуля объекта добавим проверку этого флага. Если он установлен в значение Истина, форма не открывается, все автозаполняемые реквизиты вычисляются программно, формируется ТабличныйДокумент и сразу возвращается в вызывающий код.ЭтаФорма.Закрыть(), чтобы окно не оставалось на экране пользователя.В толстом клиенте на обычных формах платформы 1С:Предприятие 8 можно инициализировать форму обработки в оперативной памяти, программно заполнить ее реквизиты и вызвать экспортные методы формирования макета, не выполняя команду Открыть().
Разберем по шагам, как реализовать этот алгоритм:
// 1. Получаем двоичные данные внешней обработки из справочника
ДвоичныеДанные = СсылкаНаВПФ.ХранилищеВнешнейОбработки.Получить();
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// 2. Создаем объект обработки
ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяВременногоФайла);
ОбработкаОбъект.СсылкаНаОбъект = Строка.ДокументРеализация;
// 3. Получаем форму обработки без вызова метода Открыть()
ФормаВПФ = ОбработкаОбъект.ПолучитьФорму("Форма");
ФормаВПФ.Документ = Строка.ДокументРеализация;
// 4. Если автозаполнение расположено в обработчике ПриОткрытии, вызываем его напрямую
ФормаВПФ.ПриОткрытии();
// 5. Вызываем экспортную функцию формирования табличного документа
ПечДокумент = ФормаВПФ.СформироватьПечатнуюФорму();
// Если макет выводится в элемент управления ПолеТабличногоДокумента на форме:
Если ПечДокумент = Неопределено Тогда
ПечДокумент = ФормаВПФ.ЭлементыФормы.ПолеТабличногоДокумента.Получить();
КонецЕсли;
// 6. Отправляем документ на печать
УниверсальныеМеханизмы.НапечататьДокумент(ПечДокумент, 2, НаПринтер, "ТТН");
// 7. Удаляем временный файл
УдалитьФайлы(ИмяВременногоФайла);
Важно: в обычных формах элементы управления (включая ПолеВвода и ПолеТабличногоДокумента) создаются и инициализируются в памяти сразу при вызове метода ПолучитьФорму(). Это позволяет обращаться к ним и считывать результаты без фактического вывода окна на экран.
Если внешняя обработка защищена паролем или модификация файла ВПФ в справочнике нежелательна, можно полностью вынести процедуру печати ТТН в модуль вашей пакетной обработки:
Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда заменим вызов УниверсальныеМеханизмы.НапечататьВнешнююФорму на локальную функцию формирования макета.Проанализируем ключевые моменты, которые необходимо учитывать при реализации пакетной печати:
Модальные вызовы: если внутри кода внешней печатной формы жестко прописан метод ОткрытьМодально(), пакетное выполнение будет заблокировано. В этом случае модальный вызов обязательно должен быть исключен либо путем правки самой ВПФ, либо переносом ее логики в пакетную обработку.
События формы: помните, что при использовании ПолучитьФорму() без Открыть() события ПередОткрытием() и ПриОткрытии() автоматически платформой не вызываются. Если логика заполнения полей завязана на них, сделайте эти процедуры экспортными и вызывайте их явным образом.