Создание внешней печатной формы (ВПФ) — одна из самых частых задач для разработчика 1С. Это позволяет изменять печатные форматы документов (например, «Счет на оплату» в 1С:Управление торговлей 11.4) без внесения изменений в основную конфигурацию. Однако при разработке новички часто сталкиваются с тем, что форма не регистрируется или выдает ошибку: «В обработчике печати не был сформирован табличный документ». В этой статье мы подробно разберем, как правильно создать ВПФ, используя механизмы Библиотеки стандартных подсистем (БСП).
Для того чтобы система «увидела» вашу обработку и поняла, к какому документу её привязать, необходимо в модуле объекта обработки создать экспортную функцию СведенияОВнешнейОбработке. Рассмотрим современный стандарт написания этой функции, который рекомендуется для актуальных версий БСП (3.0 и выше).
Вместо ручного создания структуры, как это делали в старых версиях, лучше использовать методы самой библиотеки. Это гарантирует совместимость при обновлениях системы. Проанализируем пример кода:
Функция СведенияОВнешнейОбработке() Экспорт
// Получаем версию БСП для корректной регистрации
ТекущаяВерсияБСП = СтандартныеПодсистемыСервер.ВерсияБиблиотеки();
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(ТекущаяВерсияБСП);
// Указываем тип объекта
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма;
// Массив назначений: к каким документам прикрепляем ВПФ
ПараметрыРегистрации.Назначение.Добавить("Документ.ЗаказКлиента");
ПараметрыРегистрации.Наименование = "Счет на оплату (внешний)";
ПараметрыРегистрации.Версия = "1.1";
ПараметрыРегистрации.БезопасныйРежим = Ложь; // Важно, если используете запросы к внешним данным или специфические вызовы
// Добавляем команду печати
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Счет на оплату (шаблон)";
НоваяКоманда.Идентификатор = "СчетНаОплату"; // Этот ID критически важен!
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода;
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
Важный момент: Обратите внимание на Идентификатор команды. Он должен в точности совпадать с тем именем, которое вы будете использовать в коде формирования печатной формы. Даже одна лишняя буква или разный регистр приведут к ошибке.
Главная ошибка многих разработчиков при копировании кода из модуля менеджера типового документа заключается в неверном количестве параметров. В модуле менеджера встроенного документа процедура Печать обычно принимает 5 параметров, но для внешней печатной формы их должно быть строго 4.
Разберем правильную структуру процедуры в модуле объекта ВПФ:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Проверяем, нужно ли печатать именно наш макет (по идентификатору из Сведений)
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "СчетНаОплату") Тогда
// Формируем табличный документ
ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
// Выводим результат в коллекцию
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"СчетНаОплату",
"Счет на оплату (внешний)",
ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
Выясним причину ошибки «В обработчике печати не был сформирован табличный документ». Она возникает, если функция УправлениеПечатью.НужноПечататьМакет возвращает Ложь (не совпали ИД) или если процедура ВывестиТабличныйДокументВКоллекцию не была вызвана из-за исключения в коде формирования данных.
Когда мы работаем внутри внешней обработки, мы не можем обращаться к макетам конфигурации напрямую через Документы.ЗаказКлиента.ПолучитьМакет(...). Мы должны использовать макет, который находится внутри самой обработки.
Рассмотрим, как правильно получить макет и заполнить его данными:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ЗаказКлиента_СчетНаОплату";
// Получаем макет из текущей внешней обработки
Макет = ЭтотОбъект.ПолучитьМакет("ПФ_MXL_СчетНаОплату");
// Здесь идет стандартный код запроса и вывода областей
// Для примера выведем простую область заголовка
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
Для Каждого СсылкаИзМассива Из МассивОбъектов Цикл
// Заполнение параметров области...
ОбластьЗаголовок.Параметры.ТекстЗаголовка = "Счет № " + СсылкаИзМассива.Номер;
ТабличныйДокумент.Вывести(ОбластьЗаголовок);
// Важно для корректной работы ОбъектыПечати
УправлениеПечатью.ЗаполнитьПараметрыОтправки(ПараметрыВывода.ПараметрыОтправки, СсылкаИзМассива, ТабличныйДокумент);
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Печать. Помните: во внешней форме их 4 (МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода).СведенияОВнешнейОбработке — "СчетНаОплату", а в процедуре Печать вы проверяете "ПФ_MXL_Счет", документ никогда не будет сформирован.ФормированиеПечатныхФорм.ЗаполнитьПараметрыОтправки(...) часто копируется из модуля менеджера УТ 11.4. Во внешней обработке она может вызвать ошибку, если параметры переданы неверно. Если вы не планируете использовать механизм «Печать и отправка по почте», эту строку можно опустить или заменить на упрощенный вариант.ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);.Проанализируем ситуацию: код написан, но форма выдает ошибку. Поскольку ВПФ запускается из временного хранилища, точка останова в конфигураторе может не сработать. Чтобы эффективно отладить код, используйте следующий прием:
Создайте в вашей обработке Форму. На форму добавьте кнопку и реквизит типа ДокументСсылка.ЗаказКлиента. В обработчике кнопки напишите вызов процедур из модуля объекта:
&НаСервере
Процедура КомандаОтладкаНаСервере()
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(Объект.СсылкаНаДокумент);
КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("СчетНаОплату");
ОбъектыПечати = Новый СписокЗначений;
ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
// Теперь мы можем вызвать Печать и сработает точка останова!
ОбъектВПФ = РеквизитФормыВЗначение("Объект");
ОбъектВПФ.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
// Просмотр результата
ТабДок = КоллекцияПечатныхФорм[0].ТабличныйДокумент;
ТабДок.Показать();
КонецПроцедуры
Этот метод позволяет быстро найти место, где код «спотыкается», не перезагружая каждый раз файл в справочник дополнительных обработок. Как только отладка завершена, просто удалите форму или не обращайте на неё внимания при регистрации — система использует только программный интерфейс модуля объекта.