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

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

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

Проанализируем типичную ситуацию: разработчик не может добавить новые реквизиты в сам документ через расширение из-за нестабильной работы платформы (вылеты конфигуратора), поэтому принимает решение запрашивать эти данные "на лету" через форму внешней обработки. Разберем по шагам, как правильно реализовать этот механизм в современных конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП).

Шаг 1: Правильная регистрация обработки в стандартах БСП

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

В типовом варианте для мгновенной печати используется вид команды ВызовСерверногоМетода. Нам же необходимо изменить этот параметр на один из следующих вариантов:

  1. ОткрытиеФормы — основная форма обработки откроется автоматически при вызове команды.
  2. ВызовКлиентскогоМетода — система обратится к экспортной клиентской процедуре в модуле формы, внутри которой мы сможем написать программный вызов ЭтаФорма.Открыть().

Использование команды ОткрытиеФормы является наиболее простым и предпочтительным способом для нашей задачи.

Шаг 2: Получение документов назначения при открытии формы

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("ОбъектыНазначения") Тогда
        // Сохраняем переданный массив документов в реквизит формы (тип: Произвольный или Массив)
        МассивДокументовНаПечать = Параметры.ОбъектыНазначения;
    КонецЕсли;
КонецПроцедуры

Шаг 3: Передача параметров с формы в модуль объекта

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

Для связи формы с модулем объекта мы применим функцию РеквизитФормыВЗначение. Рассмотрим код обработчика нажатия кнопки "Печать" на нашей форме:


&НаКлиенте
Процедура НапечататьДокумент(Команда)
    // Вызываем серверную функцию для формирования табличного документа
    ТабДок = СформироватьПечатнуюФормуНаСервере();
    
    // После получения макета, выводим его пользователю
    Если ТабДок <> Неопределено Тогда
        ТабДок.Показать();
    КонецЕсли;
КонецПроцедуры

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

Шаг 4: Формирование макета в модуле объекта

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

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


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

Шаг 5: Нюансы вывода на экран в новых релизах БСП

Если вы разрабатываете под свежие релизы конфигураций (например, Бухгалтерия предприятия 3.0.143+ или Управление торговлей 11.5+), стоит учитывать важный нюанс. Ранее для вывода сформированного табличного документа в штатное окно печати 1С разработчики просто открывали общую форму ПечатьДокументов. Сейчас этот подход может привести к ошибкам или пустому экрану из-за изменений в структуре служебных коллекций.

Для корректного вывода макета из пользовательской формы в стандартное окно печати БСП, рекомендуем использовать специализированный программный интерфейс:


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

Альтернативный путь: Использование дополнительных реквизитов

Проанализируем первопричину задачи: автору пришлось создавать форму-прокладку из-за того, что добавление реквизита в сам документ через расширение приводило к вылету конфигуратора.

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

Разберем этот вариант по шагам:

  1. В режиме 1С:Предприятие переходим в настройки дополнительных реквизитов.
  2. Добавляем новый реквизит "Ответственный за печать" для нужного вида документа. Это действие абсолютно безопасно, не требует изменения метаданных, не затрагивает расширения и не вызовет падение конфигуратора.
  3. Пользователь заполняет этого ответственного прямо в карточке документа на специальной вкладке или в окне дополнительных свойств.
  4. Внешнюю печатную форму мы возвращаем к стандартному виду (без открытия окна, сразу на сервер).
  5. В модуле объекта при формировании макета мы просто считываем значение этого дополнительного реквизита программно, используя типовые функции (например, УправлениеСвойствами.ЗначенияСвойств()) и подставляем его в макет.

Этот подход значительно упрощает архитектуру ВПФ, снижает вероятность ошибок при передаче контекста с клиента на сервер и делает работу пользователя более предсказуемой, так как данные об ответственном сохраняются в базе вместе с документом, а не запрашиваются заново при каждой печати.

← На главную