Как программно напечатать внешнюю печатную форму с диалоговым окном при пакетной печати в 1С 8.2 на обычных формах?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке механизмов пакетной печати документов в конфигурациях на обычных формах (например, в «1С:Управление торговлей 10.3» или «1С:Комплексная автоматизация 1.1») разработчики часто сталкиваются с ситуацией, когда типовые печатные формы выводятся без проблем, а внешние печатные формы (ВПФ) прерывают автоматический процесс. Наиболее частый пример — товарно-транспортная накладная (форма 1-Т), которая открывает диалоговое окно для заполнения сведений о перевозчике, водителе или путевом листе.

Разберем причины такого поведения и рассмотрим проверенные способы организовать бесперебойную печать внешних обработок без необходимости ручного нажатия кнопок пользователем.

Анализ типового механизма пакетной печати

Посмотрим на классический алгоритм вызова печати через типовой общий модуль УниверсальныеМеханизмы:


ДеревоМакетов = УниверсальныеМеханизмы.ПолучитьДеревоМакетовПечати(Объект.Ссылка, Объект.ПолучитьСтруктуруПечатныхФорм, , );
ИскомоеИмя = "1-Т (Товарно-транспортная накладная) внеш";
СтрМакета = ДеревоМакетов.Строки.Найти(ИскомоеИмя, "Текст");
Расшифровка = СтрМакета.Расшифровка;

Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
    ПечДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(Строка.ДокументРеализация, Расшифровка);
    УниверсальныеМеханизмы.НапечататьДокумент(ПечДокумент, 2, НаПринтер, ОбщегоНазначения.СформироватьЗаголовокДокумента(Строка.Ссылка), );
    Сообщить("Печать внешней формы: " + Строка.ДокументРеализация);
Иначе
    Объект.Печать(Расшифровка, 2, НаПринтер);
    Сообщить("Печать внутренней формы: " + Строка.ДокументРеализация);
КонецЕсли;

Функция УниверсальныеМеханизмы.НапечататьВнешнююФорму открывает внешнюю обработку и ожидает возврата сформированного табличного документа. Однако, если обработка внутри себя вызывает открытие собственной формы (через метод Форма.Открыть() или Форма.ОткрытьМодально()), выполнение потока останавливается или требует реакции пользователя.

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

Способ 1. Доработка внешней печатной формы (Рекомендуемый подход)

Если код внешней печатной формы доступен для редактирования, самым надежным и чистым решением является добавление флага пакетного режима работы.

  1. Добавление реквизита: в реквизиты внешней обработки добавим реквизит ПакетныйРежим с типом Булево.
  2. Разделение логики: в функции Печать() модуля объекта добавим проверку этого флага. Если он установлен в значение Истина, форма не открывается, все автозаполняемые реквизиты вычисляются программно, формируется ТабличныйДокумент и сразу возвращается в вызывающий код.
  3. Автоматическое закрытие: если логика жестко завязана на элементы формы, в конце процедуры формирования макета в модуле формы добавляем команду ЭтаФорма.Закрыть(), чтобы окно не оставалось на экране пользователя.

Способ 2. Программное получение формы ВПФ в памяти без визуального открытия

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

Разберем по шагам, как реализовать этот алгоритм:


// 1. Получаем двоичные данные внешней обработки из справочника
ДвоичныеДанные = СсылкаНаВПФ.ХранилищеВнешнейОбработки.Получить();
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf");
ДвоичныеДанные.Записать(ИмяВременногоФайла);

// 2. Создаем объект обработки
ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяВременногоФайла);
ОбработкаОбъект.СсылкаНаОбъект = Строка.ДокументРеализация;

// 3. Получаем форму обработки без вызова метода Открыть()
ФормаВПФ = ОбработкаОбъект.ПолучитьФорму("Форма");
ФормаВПФ.Документ = Строка.ДокументРеализация;

// 4. Если автозаполнение расположено в обработчике ПриОткрытии, вызываем его напрямую
ФормаВПФ.ПриОткрытии();

// 5. Вызываем экспортную функцию формирования табличного документа
ПечДокумент = ФормаВПФ.СформироватьПечатнуюФорму();

// Если макет выводится в элемент управления ПолеТабличногоДокумента на форме:
Если ПечДокумент = Неопределено Тогда
    ПечДокумент = ФормаВПФ.ЭлементыФормы.ПолеТабличногоДокумента.Получить();
КонецЕсли;

// 6. Отправляем документ на печать
УниверсальныеМеханизмы.НапечататьДокумент(ПечДокумент, 2, НаПринтер, "ТТН");

// 7. Удаляем временный файл
УдалитьФайлы(ИмяВременногоФайла);

Важно: в обычных формах элементы управления (включая ПолеВвода и ПолеТабличногоДокумента) создаются и инициализируются в памяти сразу при вызове метода ПолучитьФорму(). Это позволяет обращаться к ним и считывать результаты без фактического вывода окна на экран.

Способ 3. Перенос логики формирования макета в саму пакетную обработку

Если внешняя обработка защищена паролем или модификация файла ВПФ в справочнике нежелательна, можно полностью вынести процедуру печати ТТН в модуль вашей пакетной обработки:

  1. Скопируем макет печатной формы и код процедуры формирования данных непосредственно в обработку пакетной печати.
  2. В ветке условия Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда заменим вызов УниверсальныеМеханизмы.НапечататьВнешнююФорму на локальную функцию формирования макета.
  3. Если исходный алгоритм ТТН записывает дополнительные данные (например, номера путевых листов или параметры груза в регистры сведений), эти действия выполняются прямо в коде локальной функции перед отправкой табличного документа на принтер.

Важные ограничения и особенности

Проанализируем ключевые моменты, которые необходимо учитывать при реализации пакетной печати:

Модальные вызовы: если внутри кода внешней печатной формы жестко прописан метод ОткрытьМодально(), пакетное выполнение будет заблокировано. В этом случае модальный вызов обязательно должен быть исключен либо путем правки самой ВПФ, либо переносом ее логики в пакетную обработку.

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

← На главную