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