Как получить макет во внешней печатной форме для 1С:Управление торговлей 11

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке внешних печатных форм для конфигураций, построенных на базе Библиотеки стандартных подсистем (БСП), таких как 1С:Управление торговлей 11, 1С:ERP или 1С:Комплексная автоматизация, программисты часто сталкиваются с проблемой доступа к макету. Попытка использовать стандартные механизмы получения пути к макету, работающие для встроенных объектов, во внешней обработке часто приводит к ошибкам вида "Макет не найден".

В этой статье мы подробно разберем, почему стандартный подход с указанием пути через точку не работает для внешних обработок, и рассмотрим правильные способы получения макета для вывода на печать.

Почему возникает ошибка при поиске пути к макету?

Рассмотрим ситуацию: вы создаете внешнюю печатную форму и хотите использовать логику общего модуля, например, УправлениеПечатью.МакетПечатнойФормы(ПутьКМакету). Ожидается, что ПутьКМакету — это строка формата "ВидОбъекта.ИмяОбъекта.ИмяМакета" (например, "Документ.ЗаказКлиента.ПФ_MXL_ЗаказКлиента").

Проблема заключается в том, что когда внешняя обработка загружается в справочник "Дополнительные отчеты и обработки", система регистрирует её под временным внутренним именем. Это имя часто представляет собой уникальный идентификатор (GUID). Попытка прописать путь жестко, например, "ВнешняяОбработка.МояПечатнаяФорма.Макет", обречена на провал, так как имя объекта в конфигурации и имя объекта, загруженного в базу как внешнее, — это разные сущности для механизма управления печатью.

Проанализируем типичную ошибку при использовании метода ЭтотОбъект.ПолучитьМакет("Имя_Макета"). Этот метод возвращает сам объект типа ТабличныйДокумент (или двоичные данные), а не строку-путь. Если общий модуль ожидает именно строку, чтобы потом самостоятельно найти макет в метаданных, он просто "не понимает" переданный ему объект и выдает исключение.

Решение 1: Прямое получение макета в модуле объекта

Самый простой и эффективный способ во внешней обработке — отказаться от попыток получить "путь" и работать с объектом макета напрямую. Поскольку код выполняется внутри модуля самой обработки, у нас есть прямой доступ к её метаданным.

Выясним, как это выглядит на практике. Вместо вызова функций общего модуля для поиска макета, мы используем встроенный метод:


// В модуле объекта внешней обработки
ИмяМакета = "ПФ_MXL_МойМакет";
Макет = ЭтотОбъект.ПолучитьМакет(ИмяМакета);

Если вы находитесь в контексте модуля объекта, ключевое слово ЭтотОбъект указывает именно на вашу внешнюю обработку. Полученный Макет далее передается в процедуры заполнения областей данных.

Решение 2: Использование в стандартной процедуре Печать

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


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

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

Решение 3: Как получить программный путь (если это необходимо)

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

Проанализируем, как вычислить полное имя объекта во время выполнения кода:


// Получаем полное имя метаданных объекта (включая префикс ВнешняяОбработка)
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя(); 
// Результат будет примерно такой: "ВнешняяОбработка.ДополнительнаяПечатнаяФорма_12345678"

ИмяМакета = "ПФ_MXL_МойМакет";
ПолныйПутьКМакету = ПолноеИмяОбъекта + "." + ИмяМакета;

// Теперь этот путь можно передавать в функции поиска макетов
// Макет = УправлениеПечатью.МакетПечатнойФормы(ПолныйПутьКМакету);

Важный момент: Данный способ будет работать корректно только в том случае, если обработка запущена в контексте системы (через механизм дополнительных обработок). Если вы просто открываете .epf файл через меню "Файл - Открыть", метаданные могут не содержать нужного префикса для корректной работы функций БСП.

Рекомендации по разработке

  1. Не используйте жесткие ссылки: Никогда не пишите в коде внешней обработки пути вида "Обработка.МояОбработка.Макет". При загрузке в базу данных это имя изменится, и код перестанет работать.
  2. Используйте ПолучитьМакет(): Это самый надежный метод. Он ищет макет внутри "самого себя", независимо от того, как обработка называется в системе.
  3. Соблюдайте структуру БСП: Старайтесь отделять логику получения данных от логики формирования табличного документа. Передавайте уже готовый объект Макет (типа ТабличныйДокумент) в свои функции формирования, а не строку с его названием.
  4. Проверяйте тип возвращаемого значения: Метод ПолучитьМакет() может возвращать как ТабличныйДокумент, так и ДвоичныеДанные (например, если макет — это Word или Excel). Убедитесь, что ваша логика обработки соответствует типу макета.

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

← На главную