Недавно возникла необходимость написать внешнюю печатную форму (далее - ВПФ) для УТ 11.2, а опыта их создания у меня не было. Я полез искать образцы, статьи и т.д. Что-то нашел, но целостной статьи для новичков не было, поэтому захотелось написать инструкцию по созданию ВПФ для конфигурации на основе БСП - и УТ 11.2 одна из них.
УТ 11 позволяет в режиме предприятия редактировать макет печатной формы. Поэтому, если нам нужно только визуально изменить макет, то разумнее это сделать штатными средствами в пользовательском режиме. Когда же мы хотим программно вычислить и подставить определенные данные, которых нет у нас в макете, тогда уже нам не обойтись без создания ВПФ.
Приступим. Мы определились, что будем делать ВПФ для документа ЗаказКлиента. Находим его в дереве метаданных, жмем по нему правой кнопкой мыши, выбираем модуль менеджера и находим в нем такой код:
#Область Печать
// Заполняет список команд печати.
//
// Параметры:
// КомандыПечати - ТаблицаЗначений - состав полей см. в функции УправлениеПечатью.СоздатьКоллекциюКомандПечати
//
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
Если ПраваПользователяПовтИсп.СамооблуживаниеПросмотрДокументовУсловийПродаж() Тогда
// Заказ клиента
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.МенеджерПечати = "Обработка.ПечатьЗаказовНаТоварыУслуги"; // <---------
КомандаПечати.Идентификатор = "ЗаказКлиента";
КомандаПечати.Представление = НСтр("ru = 'Заказ клиента'");
КомандаПечати.ПроверкаПроведенияПередПечатью = Истина;
// Счет на оплату
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.МенеджерПечати = "Обработка.ПечатьСчетовНаОплату"; // <----------
КомандаПечати.Идентификатор = "СчетНаОплату";
КомандаПечати.Представление = НСтр("ru = 'Счет на оплату'");
КомандаПечати.ПроверкаПроведенияПередПечатью = Истина;
Несложно понять, что в зависимости от того, какой макет нам нужен (Счет на оплату, Заказ клиента и т.д.), мы должны найти соответствующую обработку в дереве метаданных.
Разворачиваем раздел Обработки в дереве метаданных и находим обработку "ПечатьЗаказовНаТоварыУслуги".
Из этой обработки мы должны скопировать модуль менеджера в свою печатную форму. Только этот код мы себе вставим в модуль объекта нашей ВПФ. И перетаскиваем себе нужный макет из этой обработки в свою.
Чтобы иметь возможность подключить эту обработку как ВПФ, мы должны вставить в модуль объекта служебные процедуры по добавлению сведений о внешней обработке:
Функция СведенияОВнешнейОбработке() экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.ЗаказКлиента"); //Указываем документ к которому делаем внешнюю печ. форму
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); //может быть - ПечатнаяФорма, ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов...
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Заказ клиента (внешний)"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ);
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("Информация", "Эту ВПФ мы сделали для того что бы посмотреть возможности БСП ");
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Заказ клиента (внешний)", "ЗаказКлиента", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));//как будет выглядеть описание печ.формы для пользователя
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка")); //имя макета печ.формы
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка")); //ВызовСерверногоМетода
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Теперь, если мы подключим нашу ВПФ и попробуем вывести ее на печать, 1С выдаст нам ошибку, что ей недостаточно физических параметров в процедуре Печать.
Сравним два фрагмента кода. Первый наш исходный
Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
а это тот, который нам нужен
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
То есть нам надо указать четыре, а не пять параметров в функции Печать(). Параметр с именем "ПараметрыПечати" убран, но он упоминается в процедуре, поэтому в начале текста процедуры мы создадим эту переменную сами.
ПараметрыПечати = Новый Структура();
И уберем или закомменируем лишний код:
//Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ПараметрыПечати = Новый Структура(); // это мы добавили сами для процедуры СформироватьПечатнуюФормуЗаказаКлиента()
СтруктураТипов = ОбщегоНазначенияУТ.СоответствиеМассивовПоТипамОбъектов(МассивОбъектов);
// Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ЗаказКлиента") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ЗаказКлиента",
НСтр("ru = 'Заказ клиента'"),
СформироватьПечатнуюФормуЗаказаКлиента(СтруктураТипов, ОбъектыПечати, ПараметрыПечати));
//КонецЕсли;
//
//Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ЗаказПоставщику") Тогда
//
// УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
// КоллекцияПечатныхФорм,
// "ЗаказПоставщику",
// НСтр("ru = 'Заказ поставщику'"),
// СформироватьПечатнуюФормуЗаказаПоставщику(СтруктураТипов, ОбъектыПечати, ПараметрыПечати));
//
//КонецЕсли;
ФормированиеПечатныхФорм.ЗаполнитьПараметрыОтправки(ПараметрыВывода.ПараметрыОтправки, СтруктураТипов, КоллекцияПечатныхФорм);
КонецПроцедуры
После этого наша ВПФ станет выводиться на печать, но макет она будет использовать из конфигурации, а не наш позаимствованный.
В процедуре СформироватьПечатнуюФормуЗаказаКлиента() вызывается в свою очередь другая процедура:
// Сформированный тбаличный документ
ЗаполнитьТабличныйДокументЗаказаНаТоварыУслуги(
ТабличныйДокумент,
ДанныеДляПечати,
ОбъектыПечати,
КомплектыПечати,
"Обработка.ПечатьЗаказовНаТоварыУслуги.ПФ_MXL_ЗаказКлиента");
Последний параметр - это имя макета печатной формы. Т.е. вместо "Обработка.ПечатьЗаказовНаТоварыУслуги.ПФ_MXL_ЗаказКлиента" мы пишем "ПФ_MXL_ЗаказКлиента" (т.е. мы указываем имя макета, который мы перетащили себе в свою обработку).
Далее идем в процедуру ЗаполнитьТабличныйДокументЗаказаНаТоварыУслуги().
Находим нижеуказанную строчку кода, закомментируем ее и вставим свою:
// это строка из конфигурации не нужна нам
//Макет = УправлениеПечатью.МакетПечатнойФормы(ИмяМакета);
// а это наш код
Макет = ПолучитьМакет(ИмяМакета);
Готово!
Подытожим. Логика была такая. Мы полезли в модуль менеджера нужного нам документа, чтобы позаимствовать код процедуры печати объекта. Нашли код и макет. Получили ошибки при формировании печатной формы. Откорректировали код процедуры печати. Нашли код, который отвечает за получение макета и подставили туда свой, чтобы использовался наш макет.
Надеюсь, что это небольшая статья прояснит какие-то моменты у новичков при создании печатных форм.