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