Как во внешней печатной форме 1С реализовать вопрос «С факсимиле или без?» перед печатью

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

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

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

Способ 1. Создание двух команд в одной внешней печатной форме

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

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

Рассмотрим по шагам реализацию этого механизма в модуле объекта нашей внешней обработки.

Шаг 1. Регистрация двух команд печати

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


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.0");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Наименование = "Расходная накладная с выбором факсимиле";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    
    // Добавляем назначение (для какого документа предназначена ВПФ)
    ПараметрыРегистрации.Назначение.Добавить("ДокументСсылка.РасходнаяНакладная");
    
    // Создаем таблицу команд
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    
    // Команда 1: Печать с факсимиле
    ДобавитьКоманду(ТаблицаКоманд,
                    "Расходная накладная (с факсимиле)",
                    "НакладнаяСФаксимиле",
                    "ВызовСерверногоМетода",
                    Истина,
                    "ПечатьMXL");
                    
    // Команда 2: Печать без факсимиле
    ДобавитьКоманду(ТаблицаКоманд,
                    "Расходная накладная (без факсимиле)",
                    "НакладнаяБезФаксимиле",
                    "ВызовСерверногоМетода",
                    Истина,
                    "ПечатьMXL");
    
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
    
    Возврат ПараметрыРегистрации;

КонецФункции

Шаг 2. Обработка команд в процедуре Печать

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


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

КонецПроцедуры

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

Способ 2. Использование клиентского метода и асинхронного диалога

Если бизнес-процесс жестко требует вывода единой кнопки в меню «Печать» и последующего вызова интерактивного окна с вопросом «Да/Нет», нам придется задействовать клиентский метод выполнения команды ВПФ.

Для реализации этого подхода необходимо:

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

Проанализируем детально программный код для каждого шага.

Шаг 1. Изменение регистрации команды в модуле объекта

В функции регистрации мы меняем режим запуска команды на клиентский вызов:


// Вместо "ВызовСерверногоМетода" указываем тип команды "ВызовКлиентскогоМетода"
ДобавитьКоманду(ТаблицаКоманд,
                "Расходная накладная",
                "РасходнаяНакладнаяДиалог",
                "ВызовКлиентскогоМетода",
                Истина,
                "ПечатьMXL");

Шаг 2. Разработка логики в модуле формы ВПФ

Создадим основную форму обработки. В модуле этой формы мы должны разместить экспортную процедуру с предопределенным именем Печать(). Именно она перехватит управление на клиенте при нажатии кнопки в меню документа.

Поскольку модальные диалоги заблокированы, мы конструируем описание оповещения (объект ОписаниеОповещения), которое укажет платформе, какую процедуру нужно запустить после того, как пользователь нажмет кнопку «Да» или «Нет» в окне вопроса.


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

Шаг 3. Обработка выбора пользователя и вывод печатной формы

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


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

Шаг 4. Серверная генерация табличного документа

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


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

Сравнение подходов и выводы

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

Метод с двумя командами (Способ 1) является максимально надежным. Он полностью соответствует философии разработки БСП и механизмов интеграции внешних обработок. При обновлении конфигурации или изменении платформы такой код гарантированно не сломается. Пользователям не приходится совершать «лишние клики» во всплывающих окнах — они сразу выбирают целевое действие.

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

← На главную