diamond АШ Tlg

Разработка внешней печатной формы с формой диалога ввода параметров, 1С БСП 3.1.9

"Обратная совместимость? Неее, не слышали )". После обновления на последние релизы во многих типовых конфигурациях (например ЗУП 3.1.27) ломаются древние внешние печатные формы, из-за сущности "КоллекцияПечатныхФорм". Причина в новом БСП 3.1.9, а значит фирма 1С решила снова взбодрить программистов и пришло время освежить всем свои шпаргалки.

В качестве примера разработаем внешнюю печатную форму для элемента справочника 'Сотрудники'. Создаём новую внешнюю обработку (epf). Весь код будет размещён в 3-х разных местах.

Модуль объекта

Стандартное описание внешней обработки, согласно спецификации БСП:

#Область ПрограммныйИнтерфейс_ПодсистемаПечатьБСП

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

    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    ПараметрыРегистрации.Назначение = СтрРазделить("Справочник.Сотрудники", ",", Ложь);
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0.0.1";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Наименование = НСтр("ru = 'Доп соглашение'");	

    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Доп соглашение'");
    НоваяКоманда.Идентификатор = "ид_ДопСоглашение";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    НоваяКоманда.Модификатор = "ПечатьMXL";
		
    Возврат ПараметрыРегистрации;
	
КонецФункции

В описании важно указать, что вид обработки это 'Печатная Форма', а вид использования команды - 'Вызов Клиентского Метода'. Идентификатор команды позднее будет передаваться подсистеме печати БСП в качестве наименования макета.

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

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

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

#КонецОбласти

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

Функция ПечатьДоговора(МассивОбъектов, ОбъектыПечати)

    Макет = ПолучитьМакет("Макет");
    ТабДокумент = Новый ТабличныйДокумент;
    ТабДокумент.КлючПараметровПечати = "ПараметрыПечати_ДопСоглашение";

    // МассивОбъектов - это массив структур с параметрами, которые мы будем формировать 
    // сами в дополнительной форме диалога перед печатью

    Для Каждого Парам Из МассивОбъектов Цикл
        Если Парам.Печать = Истина Тогда
            Сотрудник = Парам.Сотрудник;
            ТекстДопСоглашения = Парам.ТекстДопСоглашения;

            /////// здесь заполняем табличный документ по своему усмотрению ////////

        КонецЕсли;
    КонецЦикла;

    Возврат ТабДокумент;
	
КонецФункции

Основная форма обработки

Создаем новую форму обработки, назовём её Клиентский метод и обязательно назначаем основной формой:

основная форма обработки

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

Параметры формы клиентского вызова

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

#Область ПрограммныйИнтерфейс_БСП

&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
	
    Если ОбъектыНазначенияМассив.Количество() > 1 Тогда
        ОбщегоНазначенияКлиент.СообщитьПользователю("Печатная форма не предназначена для множественного выбора объектов. Выберите только один!");
        Возврат;
    КонецЕсли;

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаКлиенте
Процедура ПечатьЗавершение(Результат, ДополнительныеПараметры) Экспорт

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

            // Открытие формы диалога
            ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия);
			
        КонецЕсли;
		
    КонецЕсли;
	
КонецПроцедуры

Процедура СформироватьПечатныеФормы(ПараметрыОткрытия)

    Результат = Неопределено; 
    ОбъектыПечати = Новый СписокЗначений;    
    ПараметрыВывода = Неопределено;

    УправлениеПечатью.ПечатьПоВнешнемуИсточнику(
        ПараметрыОткрытия.ИсточникДанных,
        ПараметрыОткрытия.ПараметрыИсточника,
        Результат,
        ОбъектыПечати,
        ПараметрыВывода
    ); 

    ПараметрыОткрытия.КоллекцияПечатныхФорм = Общегоназначения.ТаблицаЗначенийВМассив(Результат);	
		
КонецПроцедуры

#КонецОбласти

Форма диалога ввода параметров

Создаём новую форму, назовём её ФормаВвода. В качестве примера добавляем реквизиты с наименованиями Дата, Сотрудник и ТекстДопСоглашения. В модуле формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        
    Дата = ТекущаяДатаСеанса();       // Инициализируем реквизит формы 'Дата'
    Сотрудник = Параметры.Сотрудник;  // Получаем ссылку на сотрудника из формы 'Клиенский метод'
    
    // Пишем эту процедуру, если необходимо что-то еще заполнить исходя из параметров формы:
    ИнициализироватьДанные();         
        
КонецПроцедуры

&НаСервере
Процедура ИнициализироватьДанные()
    
    /////// заполнение полей формы первоначальными данными /////////
    ТекстДопСоглашения = ...

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

Добавляем новую команду с любым именем, например ВывестиНаПросмотр и в его обработчике пишем:

&НаКлиенте
Процедура ВывестиНаПросмотр(Команда)
	
    ЭтаФорма.Закрыть(Новый Структура(
        "Сотрудник, Дата, ТекстДопСоглашения, Печать",
        Сотрудник, Дата, ТекстДопСоглашения, Истина
    ));
	
КонецПроцедуры

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