Как добавить выбор внешних печатных форм на управляемую форму в конфигурации УПП

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

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

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

Почему стандартный механизм не работает «из коробки»

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

Шаг 1. Создание команды печати на управляемой форме

Рассмотрим процесс подготовки формы. Прежде всего, нам нужно создать команду, которая будет инициировать процесс печати. В редакторе управляемой формы перейдем на закладку «Команды» и добавим новую команду, назовем ее КомандаПечать. Перетащим ее на панель команд формы.

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

Шаг 2. Получение списка доступных печатных форм (Сервер)

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


&НаСервере
Функция ПолучитьСписокВнешнихПечатныхФорм()
    СписокФорм = Новый СписокЗначений;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ВнешниеОбработкиПринадлежность.Ссылка КАК Ссылка,
        |	ВнешниеОбработкиПринадлежность.Ссылка.Наименование КАК Наименование
        |ИЗ
        |	Справочник.ВнешниеОбработки.Принадлежность КАК ВнешниеОбработкиПринадлежность
        |ГДЕ
        |	ВнешниеОбработкиПринадлежность.Ссылка.ВидОбработки = ЗНАЧЕНИЕ(Перечисление.ВидыДополнительныхВнешнихОбработок.ПечатнаяФорма)
        |	И ВнешниеОбработкиПринадлежность.Объект = &ТипОбъекта";
        
    // Получаем тип метаданных текущего документа
    Запрос.УстановитьПараметр("ТипОбъекта", Объект.Ссылка.Метаданные());
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        СписокФорм.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;
    
    Возврат СписокФорм;
КонецФункции

Шаг 3. Реализация выбора и вызова печати

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


&НаКлиенте
Процедура КомандаПечать(Команда)
    
    СписокВПФ = ПолучитьСписокВнешнихПечатныхФорм();
    
    Если СписокВПФ.Количество() = 0 Тогда
        // Если внешних нет, вызываем встроенную печать из модуля менеджера
        ВыполнитьПечатьВстроеннойФормы();
    ИначеЕсли СписокВПФ.Количество() = 1 Тогда
        // Если одна внешняя, запускаем ее
        ВыполнитьПечатьВнешнейФормы(СписокВПФ[0].Значение);
    Иначе
        // Если много - предлагаем выбор
        СписокВПФ.ПоказатьВыборЭлемента(Новый ОписаниеОповещения("ПослеВыбораПечатнойФормы", ЭтотОбъект), "Выберите форму для печати");
    КонецЕсли;
    
КонецПроцедуры

Шаг 4. Выполнение кода внешней обработки

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

Важно: Убедитесь, что ваша внешняя печатная форма адаптирована. В модуле объекта должна быть экспортная функция, возвращающая ТабличныйДокумент.


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

Использование БСП для упрощения задачи

Если в вашу версию УПП интегрированы элементы Библиотеки стандартных подсистем (БСП), задачу можно решить значительно элегантнее. Вместо ручного перебора справочников мы можем использовать методы подсистемы УправлениеПечатью.

Разберем, как это работает. В процедуре ПриСозданииНаСервере управляемой формы вызывается специальный метод, который автоматически находит все подключенные формы и создает кнопки на форме:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Инициализация кнопок печати через БСП
    УправлениеПечатью.ПриСозданииНаСервере(ЭтаФорма, Элементы.ГруппаКомандыПечати);
КонецПроцедуры

Этот метод самостоятельно анализирует и встроенные макеты в модуле менеджера, и дополнительные обработки из справочника ДополнительныеОтчетыИОбработки (аналог Внешних обработок в БСП). Это избавляет от необходимости писать запросы к справочникам вручную.

Особенности и нюансы контекста

Рассмотрим критические моменты, которые часто упускают из виду:

  1. Безопасный режим: При создании внешней обработки методом ВнешниеОбработки.Создать(), второй параметр отвечает за безопасный режим. Если обработка требует доступа к файловой системе или интернету, убедитесь в правильности настроек прав.
  2. Передача данных: Помните, что ТабличныйДокумент — это объект, который хорошо передается между сервером и клиентом в 8.3, поэтому вы можете сформировать его на сервере и вернуть на клиент для метода Показать().
  3. Модуль менеджера: Для встроенных форм логику формирования данных всегда следует выносить в модуль менеджера документа в процедуру Печать. Это позволит вызывать ее как из обычных, так и из управляемых форм без дублирования кода.

Выясним причину, по которой автор сообщения №6 решил добавить функцию именно в общий модуль. Это сделано для возможности повторного использования кода. Если у вас в системе планируется несколько документов на управляемых формах, создание единого метода ОткрытьФормуВыбораПечатныхФормОбъекта в общем модуле с признаком «Сервер, Вызов сервера» станет наиболее правильным архитектурным решением.

Таким образом, мы выяснили, что даже в старых конфигурациях работа с управляемыми формами может быть полноценной, если правильно разделить логику получения списка доступных форм на сервере и визуальное представление этого списка на клиенте.

← На главную