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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке внешних печатных форм (ВПФ) программисты часто сталкиваются с ситуацией, когда механизм печати используется не по прямому назначению. Например, необходимо по кнопке «Печать» не выводить бумажную форму, а выполнить какое-то действие: отправить данные в стороннюю систему, создать связанный документ или, как в нашем случае, открыть письмо в Outlook с заполненными данными о заказе. Однако при использовании стандартного шаблона ВПФ система 1С настойчиво открывает пустое окно предварительного просмотра, которое мешает пользователю. Разберем подробно, почему это происходит и как правильно реализовать задачу без лишних окон.

Почему открывается пустое окно и возникает ошибка «Табличный документ не сформирован»?

Проанализируем работу Библиотеки стандартных подсистем (БСП). Когда мы регистрируем внешнюю обработку с видом ПечатнаяФорма и указываем способ использования ВызовСерверногоМетода, система ожидает, что экспортная процедура Печать в модуле объекта заполнит коллекцию печатных форм хотя бы одним табличным документом.

Если мы просто выполняем код (например, запуск COM-объекта Outlook) и не возвращаем ТабличныйДокумент, БСП выдает исключение в общем модуле УправлениеПечатью. Если же мы возвращаем пустой ТабличныйДокумент, система считает свою работу выполненной и открывает стандартную форму предварительного просмотра, которая в данном случае оказывается пустой. Рассмотрим, как этого избежать.

Решение №1: Смена вида обработки на «Заполнение объекта»

Это самый правильный и архитектурно верный способ с точки зрения БСП. Если ваша задача — выполнить алгоритм без вывода макета на экран, то использование категории «Печатная форма» является семантической ошибкой. Нам следует изменить тип обработки на ЗаполнениеОбъекта. В этом случае кнопка появится не в подменю «Печать», а в меню «Изменить» или «Заполнение», и система не будет ожидать возврата печатных форм.

Рассмотрим, как изменить функцию СведенияОВнешнейОбработке:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.3.1.73");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Назначение.Добавить("Документ.уатЗаказГрузоотправителя");
    ПараметрыРегистрации.Наименование = "Отправка заказа в Outlook";
    ПараметрыРегистрации.Версия = "1.2";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;

    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Отправить инфо руководителю";
    НоваяКоманда.Идентификатор = "ОтправитьOutlook";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
    НоваяКоманда.ПоказыватьОповещение = Истина;

    Возврат ПараметрыРегистрации;
КонецФункции

В этом случае в модуле объекта вместо процедуры Печать необходимо использовать процедуру ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив). После завершения этой процедуры никакие окна печати открываться не будут.

Решение №2: Использование клиентского метода вызова

Если заказчик настаивает на том, чтобы кнопка находилась именно в меню Печать, нам придется обойти механизмы БСП. Для этого в параметрах регистрации команды укажем использование ВызовКлиентскогоМетода. Это позволит нам полностью контролировать процесс на стороне клиента и завершить выполнение кода до того, как в дело вступит типовое управление печатью.

Выполним следующие шаги:

  1. В функции СведенияОВнешнейОбработке укажем ТипКомандыВызовКлиентскогоМетода().
  2. Создадим в обработке Основную форму.
  3. В модуле этой формы пропишем экспортную процедуру Печать.

Посмотрим на пример реализации в модуле формы:


&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
    
    // Выполняем логику по запуску Outlook
    Для Каждого СсылкаНаОбъект Из ОбъектыНазначенияМассив Цикл
        Попытка
            Outlook = Новый COMОбъект("Outlook.Application");
            Письмо = Outlook.CreateItem(0);
            Письмо.Subject = "Информация по заказу: " + СсылкаНаОбъект;
            // Здесь можно вызвать серверный метод для получения данных заказа
            Письмо.Body = ПолучитьТекстПисьмаНаСервере(СсылкаНаОбъект);
            Письмо.Display(); // Отображаем письмо пользователю
        Исключение
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Ошибка при запуске Outlook: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
    
    // Важный момент: мы просто завершаем процедуру. 
    // Поскольку это клиентский вызов обработки, БСП не ждет возврата ТабДока.
КонецПроцедуры

Решение №3: Скрытие окна через «хитрый» возврат в серверном методе

Если вы все же используете ВызовСерверногоМетода в рамках Вид = ПечатнаяФорма, попробуйте проанализировать структуру ПараметрыВывода. В некоторых версиях БСП можно установить параметр ПараметрыВывода.ДополнительныеПараметрыПечати или попытаться очистить КоллекцияПечатныхФорм непосредственно перед выходом из процедуры, но это часто приводит к ошибке «В обработчике печати не был сформирован табличный документ», так как стандартный код БСП делает проверку:


Если ПечатнаяФорма.ТабличныйДокумент = Неопределено Тогда
    // Вызов исключения, который мы видели в Сообщении 3
КонецЕсли;

Следовательно, если мы остаемся в рамках серверного вызова печатной формы, нам обязательно нужно вернуть ТабличныйДокумент, а значит, окно печати неизбежно откроется. Именно поэтому Решение №1 и Решение №2 являются единственно рабочими для того, чтобы убрать лишний макет.

Особенности работы с Outlook через COM

Разберем важный нюанс, упомянутый в обсуждении. Использование Письмо.Display() открывает окно Outlook поверх 1С. Если ваша задача — отправить письмо мгновенно без участия пользователя, используйте Письмо.Send().

Важно: При работе в серверном контексте (ВызовСерверногоМетода) COM-объект будет пытаться создаться на сервере приложений 1С. Это сработает только если Outlook установлен непосредственно на сервере и у пользователя, под которым запущена служба 1С, есть соответствующие права. В 99% случаев запуск Outlook нужно делать на клиенте (через ВызовКлиентскогоМетода), так как почтовый клиент установлен на рабочем месте пользователя.

Проанализируем итоговый алгоритм действий для исправления вашей ситуации:

  1. Меняем в СведенияОВнешнейОбработке тип на ЗаполнениеОбъекта.
  2. Переносим код из Печать() в ВыполнитьКоманду() в модуле объекта.
  3. Убираем создание пустого ТабличныйДокумент и его возврат.
  4. Наслаждаемся отсутствием лишних окон в интерфейсе.

Использование правильных типов метаданных для внешних обработок — залог стабильной работы системы и отсутствия "костылей" в коде.

← На главную