При разработке внешних печатных форм для конфигураций на платформе 1С часто возникает ситуация, когда имя макета во внешней обработке совпадает с именем макета, уже существующего в конфигурации. В таких случаях вызов метода ПолучитьМакет может приводить к неожиданному результату: платформа обращается к объекту метаданных в конфигурации, игнорируя ваш файл внешней обработки. Давайте разберемся, почему это происходит и как гарантированно получить нужный макет.
Основная причина кроется в контексте выполнения кода. Когда вы вызываете метод ПолучитьМакет() без указания конкретного объекта, система пытается найти макет в текущем контексте исполнения. Если в конфигурации имеется объект с аналогичным именем или если вызов происходит из глобального контекста, платформа выбирает приоритетный объект из состава конфигурации. Чтобы избежать этой путаницы, необходимо явно указывать, к какому экземпляру объекта обработки мы обращаемся.
Если вы пишете код в модуле объекта самой внешней обработки (например, в процедуре печати, которая находится в модуле объекта), самым простым и надежным способом будет обращение через свойство ЭтотОбъект. Это свойство однозначно указывает платформе, что поиск необходимо производить внутри текущего экземпляра обработки, а не в глобальном контексте метаданных.
Рассмотрим пример правильного вызова:
// В модуле объекта внешней обработки
Процедура Печать() Экспорт
// Явное указание на текущий экземпляр обработки
Макет = ЭтотОбъект.ПолучитьМакет("ИмяВашегоМакета");
// Дальнейшая работа с макетом...
КонецПроцедуры
Использование ЭтотОбъект позволяет отсечь все попытки системы «заглянуть» в конфигурацию, так как ссылка на конкретный объект внешней обработки уже определена.
Если ваша логика выполняется в модуле формы, ситуация становится несколько иной. Платформа 1С разделяет данные формы и данные самого объекта. Для того чтобы получить полноценный объект обработки со всеми его методами (включая ПолучитьМакет), необходимо выполнить преобразование данных реквизита формы в значение.
Выполним это в несколько шагов:
ВнешняяОбработкаОбъект.РеквизитФормыВЗначение, чтобы извлечь объект.Посмотрим на пример кода для серверного контекста:
&НаСервере
Процедура ПолучитьМакетНаСервере()
// Извлекаем объект из реквизита формы с именем "Объект"
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Теперь вызываем метод макета у полученного объекта
Макет = ОбработкаОбъект.ПолучитьМакет("ИмяВашегоМакета");
КонецПроцедуры
Важно помнить, что РеквизитФормыВЗначение создает копию объекта на сервере, что дает нам доступ к методам, отсутствующим у элементов формы напрямую.
Если печатная форма подключается через механизмы БСП (Библиотеки Стандартных Подсистем) или вы программно управляете вызовом из другого модуля, вы можете создать экземпляр обработки динамически. Метод ВнешниеОбработки.Создать позволяет получить объект, из которого можно вызвать ПолучитьМакет с гарантией того, что будет взят файл именно из внешней обработки.
Пример использования менеджера внешних обработок:
// Создаем объект по пути к файлу
ВнешняяОбработка = ВнешниеОбработки.Создать("C:\МоиОбработки\УниверсальныйПередаточныйДокумент.epf");
// Получаем макет из созданного экземпляра
Макет = ВнешняяОбработка.ПолучитьМакет("ИмяВашегоМакета");
Этот способ особенно полезен, когда печать инициируется из стороннего кода, не имеющего прямой связи с текущим экземпляром обработки. При этом всегда проверяйте, что файл обработки доступен и к нему есть права доступа у пользователя.
Для корректной работы с макетами во внешних печатных формах придерживайтесь следующих правил:
ПолучитьМакет() без уточняющего объекта, если имя макета не является уникальным в масштабах всей конфигурации.ЭтотОбъект.ПолучитьМакет().РеквизитФормыВЗначение("ИмяРеквизита").ВнешниеОбработки.Создать() для формирования контекста.Применяя эти простые рекомендации, вы избежите ошибок обращения к «чужим» макетам и сделаете код своей внешней печатной формы стабильным и предсказуемым.