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

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

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

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

В чем разница между ручным выводом и механизмами БСП

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

Стандартный механизм БСП работает по другому принципу:

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

Наша цель — перенаправить вызов из нашей команды в этот стандартный конвейер БСП.

Рассмотрим два основных варианта реализации этой задачи: через сохранение существующей команды и через переход на полностью динамические подключаемые команды печати БСП.


Вариант 1. Сохранение существующей команды метаданных с перенаправлением в БСП

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

Шаг 1. Переделываем модуль команды на клиенте

В исходном варианте в модуле команды выполнялся вызов серверной процедуры, которая возвращала табличный документ для отображения. Теперь мы заменим этот вызов обращением к общему модулю БСП.

Откроем модуль нашей команды и приведем процедуру ОбработкаКоманды к следующему виду:


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

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

Шаг 2. Создаем или дополняем процедуру Печать в модуле менеджера

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

Разберем структуру этой процедуры:


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

Шаг 3. Реализация функции формирования табличного документа

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


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

Благодаря использованию метода УправлениеПечатью.ЗадатьОбластьПечатиДокумента БСП будет четко понимать, где в общем табличном документе заканчивается один документ и начинается другой. Это позволит пользователям выборочно отправлять по почте только конкретные документы из общего пакета.


Вариант 2. Полный переход на стандартные подключаемые команды БСП

Если вы хотите сделать решение максимально красивым и соответствующим стандартам разработки 1С, рекомендуется полностью отказаться от создания отдельных команд в дереве метаданных. Подсистема «Печать» БСП позволяет автоматически внедрять кнопки печати во все нужные формы списков и документов.

Для этого выполним несколько шагов.

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

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


// Определяет список команд печати, предоставляемых объектом
//
// Параметры:
//   КомандыПечати - ТаблицаЗначений - Таблица для добавления настроек команд
//
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
    
    // Добавляем команду для Акта перемещения
    Команда = КомандыПечати.Добавить();
    Команда.Идентификатор = "АктПеремещения";
    Команда.Представление = НСтр("ru = 'Акт перемещения бланков'");
    Команда.ПроверкаПроведенияПередПечатью = Истина; // Документ должен быть проведен
    Команда.Порядок = 10; // Порядок расположения кнопки в меню "Печать"
    
КонецПроцедуры

Шаг 2. Подключение механизма в общих модулях конфигурации

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

Добавим имя нашего документа в массив регистрируемых объектов:


Процедура ПриОпределенииОбъектовСКомандамиПечати(СписокОбъектов) Экспорт
    
    // Добавляем наш новый документ в список объектов, поддерживающих печать БСП
    СписокОбъектов.Добавить(Документы.ДвижениеБланков);
    
КонецПроцедуры

Шаг 3. Инициализация команд в формах документа и списка

Чтобы кнопки печати автоматически появились на форме документа и в форме списка, нам нужно добавить вызов БСП в модули этих форм.

В модуле формы документа и в модуле формы списка найдем (или создадим) обработчик события ПриСозданииНаСервере и добавим вызов инициализации:


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

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


Дополнительные возможности: передача параметров и отправка почты

Разберем несколько важных практических нюансов, которые часто вызывают вопросы при переходе на БСП.

Передача произвольных параметров из формы

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

При вызове на клиенте мы можем заполнить эту структуру:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    // Задаем дополнительные параметры
    ПараметрыПечати = Новый Структура;
    ПараметрыПечати.Вставить("ВыводитьПодписи", Ложь);
    ПараметрыПечати.Вставить("ДополнительноеПримечание", "Печать из архива");
    
    УправлениеПечатьюClient.ВыполнитьКомандуПечати(
        "Документ.ДвижениеБланков", "АктПеремещения", ПараметрКоманды, 
        ПараметрыВыполненияКоманды.Источник, ПараметрыПечати
    );
    
КонецПроцедуры

В модуле менеджера мы с легкостью считываем эти параметры:


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

Как гарантировать работу кнопки «Отправить сообщение»

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

Для этого используется структура ПараметрыВывода.ПараметрыОтправки. Проанализируем пример ее заполнения:


// Внутри процедуры Печать() в модуле менеджера:
ПараметрыОтправки = ПараметрыВывода.ПараметрыОтправки;

// Задаем тему письма по умолчанию
ПараметрыОтправки.Тема = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
    НСтр("ru = 'Документ перемещения бланков № %1 от %2'"), 
    ОбъектСсылка.Номер, 
    Формат(ОбъектСсылка.Дата, "ДФ=dd.MM.yyyy")
);

// Если в документе есть контрагент, можно сразу подставить его email
Если ОбщегоНазначения.ЕстьРеквизитОбъекта("Контрагент", ОбъектСсылка) Тогда
    EmailПолучателя = УправлениеКонтактнойИнформацией.ПолучитьАдресЭлектроннойПочты(ОбъектСсылка.Контрагент);
    Если ЗначениеЗаполнено(EmailПолучателя) Тогда
        ПараметрыОтправки.Получатель = EmailПолучателя;
    КонецЕсли;
КонецЕсли;

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

Резюме

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

← На главную