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

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

В процессе работы с 1С часто возникает задача: для одного документа нужно иметь несколько вариантов печатных форм. Классический пример — документ, отражающий взаимоотношения с двумя контрагентами, например, поставщиком и покупателем. Хочется, чтобы в меню "Печать" были две разные кнопки: "Заказ Поставщику" и "Заказ Покупателя". При этом логично реализовать обе формы в рамках одной внешней обработки.

В старых конфигурациях, таких как "Бухгалтерия предприятия 2.0", для этого можно было при регистрации печатной формы задать дополнительные параметры и на их основе управлять логикой печати. Однако в современных конфигурациях на управляемых формах, в частности в БП 3.0, этот механизм изменился. Разберем, как правильно решить эту задачу, используя современный подход, рекомендованный фирмой "1С".

Основной принцип: использование нескольких команд печати

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

Этот подход имеет ряд преимуществ:

Рассмотрим реализацию по шагам.

Шаг 1: Настройка функции `СведенияОВнешнейОбработке()`

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

Проанализируем структуру кода. Для каждой команды мы создаем новый элемент в коллекции `ПараметрыРегистрации.Команды` и заполняем его свойства. Самые важные из них:

Посмотрим на пример кода для регистрации двух команд: "Заказ Поставщику" и "Заказ Покупателя" для нашего самописного документа "ЗаказНаПеремещение".


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

    ПараметрыРегистрации = Новый Структура;
    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
    ПараметрыРегистрации.Вставить("Наименование", "Заказы (Поставщику и Покупателю)");
    ПараметрыРегистрации.Вставить("Версия", "1.0");
    ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
    ПараметрыРегистрации.Вставить("Информация", "Печать заказов для поставщика и покупателя");

    // Создаем таблицу команд
    Команды = Новый ТаблицаЗначений;
    Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
    Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
    Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));

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

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

    Возврат ПараметрыРегистрации;

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

После регистрации такой обработки в справочнике Дополнительные отчеты и обработки в указанном документе в подменю "Печать" появятся две новые строки.

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

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

Идентификатор вызванной команды передается в параметре ПараметрыВывода. Это структура, у которой может быть свойство ИдентификаторКоманды. Проанализировав его значение, мы можем запустить формирование нужного макета.

Рассмотрим пример реализации процедуры Печать().


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

    // Получаем идентификатор команды, которую выбрал пользователь.
    ИдентификаторКоманды = ПараметрыВывода.ИдентификаторКоманды;

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

        // Выводим результат
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм,
            "ЗаказПокупателя", // Имя для области макета
            "Заказ Покупателя", // Синоним
            ТабличныйДокумент
        );
        
    КонецЕсли;

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

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

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

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

Альтернативный вариант: промежуточная форма выбора

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

Почему этот вариант хуже?

  1. Он нарушает стандартный пользовательский опыт. Пользователь ожидает, что печатная форма появится сразу после нажатия на кнопку в меню "Печать".
  2. Он требует создания и поддержки дополнительного объекта — формы выбора, что усложняет разработку.
  3. Он не соответствует рекомендациям по разработке на платформе 1С:Предприятие 8.

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

← На главную