При разработке внешних печатных форм для конфигураций, построенных на базе Библиотеки стандартных подсистем (БСП), таких как 1С:Управление торговлей 11, 1С:ERP или 1С:Комплексная автоматизация, программисты часто сталкиваются с проблемой доступа к макету. Попытка использовать стандартные механизмы получения пути к макету, работающие для встроенных объектов, во внешней обработке часто приводит к ошибкам вида "Макет не найден".
В этой статье мы подробно разберем, почему стандартный подход с указанием пути через точку не работает для внешних обработок, и рассмотрим правильные способы получения макета для вывода на печать.
Рассмотрим ситуацию: вы создаете внешнюю печатную форму и хотите использовать логику общего модуля, например, УправлениеПечатью.МакетПечатнойФормы(ПутьКМакету). Ожидается, что ПутьКМакету — это строка формата "ВидОбъекта.ИмяОбъекта.ИмяМакета" (например, "Документ.ЗаказКлиента.ПФ_MXL_ЗаказКлиента").
Проблема заключается в том, что когда внешняя обработка загружается в справочник "Дополнительные отчеты и обработки", система регистрирует её под временным внутренним именем. Это имя часто представляет собой уникальный идентификатор (GUID). Попытка прописать путь жестко, например, "ВнешняяОбработка.МояПечатнаяФорма.Макет", обречена на провал, так как имя объекта в конфигурации и имя объекта, загруженного в базу как внешнее, — это разные сущности для механизма управления печатью.
Проанализируем типичную ошибку при использовании метода ЭтотОбъект.ПолучитьМакет("Имя_Макета"). Этот метод возвращает сам объект типа ТабличныйДокумент (или двоичные данные), а не строку-путь. Если общий модуль ожидает именно строку, чтобы потом самостоятельно найти макет в метаданных, он просто "не понимает" переданный ему объект и выдает исключение.
Самый простой и эффективный способ во внешней обработке — отказаться от попыток получить "путь" и работать с объектом макета напрямую. Поскольку код выполняется внутри модуля самой обработки, у нас есть прямой доступ к её метаданным.
Выясним, как это выглядит на практике. Вместо вызова функций общего модуля для поиска макета, мы используем встроенный метод:
// В модуле объекта внешней обработки
ИмяМакета = "ПФ_MXL_МойМакет";
Макет = ЭтотОбъект.ПолучитьМакет(ИмяМакета);
Если вы находитесь в контексте модуля объекта, ключевое слово ЭтотОбъект указывает именно на вашу внешнюю обработку. Полученный Макет далее передается в процедуры заполнения областей данных.
Согласно стандартам БСП, внешняя печатная форма должна содержать экспортную процедуру Печать. Рассмотрим, как правильно интегрировать получение макета в эту структуру, чтобы не возникало конфликтов с общими модулями системы.
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Проверяем, нужна ли печать именно нашей формы
ПараметрыПечати = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "МояУникальнаяКомандаПечати");
Если ПараметрыПечати <> Неопределено Тогда
// Получаем макет напрямую из текущего объекта
ТабДок = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
// Передаем сформированный документ в коллекцию
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"МояУникальнаяКомандаПечати",
"Заголовок формы",
ТабДок);
КонецЕсли;
КонецПроцедуры
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
// Получаем макет из метаданных внешней обработки
Макет = ПолучитьМакет("ПФ_MXL_ЗаказКлиента");
ТабДок = Новый ТабличныйДокумент;
ТабДок.КлючПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ЗАКАЗ_КЛИЕНТА";
// Логика заполнения макета данными...
// ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
// ТабДок.Вывести(ОбластьЗаголовок);
Возврат ТабДок;
КонецФункции
В редких случаях, когда вы используете специфические функции БСП, которые категорически требуют строку пути, этот путь можно сформировать динамически. Помните, что имя внешней обработки в справочнике Дополнительные отчеты и обработки отличается от имени файла.
Проанализируем, как вычислить полное имя объекта во время выполнения кода:
// Получаем полное имя метаданных объекта (включая префикс ВнешняяОбработка)
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
// Результат будет примерно такой: "ВнешняяОбработка.ДополнительнаяПечатнаяФорма_12345678"
ИмяМакета = "ПФ_MXL_МойМакет";
ПолныйПутьКМакету = ПолноеИмяОбъекта + "." + ИмяМакета;
// Теперь этот путь можно передавать в функции поиска макетов
// Макет = УправлениеПечатью.МакетПечатнойФормы(ПолныйПутьКМакету);
Важный момент: Данный способ будет работать корректно только в том случае, если обработка запущена в контексте системы (через механизм дополнительных обработок). Если вы просто открываете .epf файл через меню "Файл - Открыть", метаданные могут не содержать нужного префикса для корректной работы функций БСП.
"Обработка.МояОбработка.Макет". При загрузке в базу данных это имя изменится, и код перестанет работать.Макет (типа ТабличныйДокумент) в свои функции формирования, а не строку с его названием.ПолучитьМакет() может возвращать как ТабличныйДокумент, так и ДвоичныеДанные (например, если макет — это Word или Excel). Убедитесь, что ваша логика обработки соответствует типу макета.Подводя итог, можно сказать: основная ошибка автора вопроса заключалась в попытке передать объект (результат функции ПолучитьМакет) туда, где ожидалась строка пути. Переход к прямой работе с макетом внутри модуля обработки полностью решает эту проблему и делает код более стабильным и независимым от окружения.