При разработке внешних обработок на управляемых формах нередко возникает необходимость отобразить встроенную HTML-страницу или отчет в специальном элементе формы. Однако попытка получить макет обработчика стандартной функцией ПолучитьОбщийМакет() приводит к ошибке: «Недопустимое значение параметра (параметр номер '1')». Разберем по шагам, почему возникает эта ошибка и как правильно загрузить макет HTML во внешней обработке.
Проанализируем исходный код, вызвавший исключение:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
поле = ПолучитьОбщийМакет("my").ПолучитьТекст();
КонецПроцедуры
Метод глобального контекста ПолучитьОбщийМакет() предназначен исключительно для работы с макетами из ветки «Общие макеты» конфигурации метаданных. Если макет размещен внутри самой внешней обработки, платформа не сможет найти его в общем дереве конфигурации, о чем и сообщает текст ошибки о недопустимом значении параметра.
Макеты, принадлежащие конкретной обработке, должны получаться через метод ПолучитьМакет() соответствующего объекта обработки.
Рассмотрим правильный порядок действий на управляемой форме при наличии основного реквизита Объект.
В контексте серверных процедур управляемой формы для преобразования реквизита формы в серверный объект используется метод РеквизитФормыВЗначение("Объект"). Обратите внимание, что сокращенный вызов РеквизитВЗначение() в платформе 1С отсутствует и приведет к ошибке компиляции.
У полученного объекта вызываем метод ПолучитьМакет("ИмяМакета").
Элемент управления с видом «Поле HTML документа» связывается с реквизитом формы строкового типа неограниченной длины. Чтобы страница отобразилась в интерфейсе, присваиваем полученный текст именно этому реквизиту формы.
Посмотрим на пример корректного кода в модуле формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Преобразуем данные формы в прикладной объект
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Получаем макет и считываем его текст
ТекстHTML = ОбработкаОбъект.ПолучитьМакет("МойМакетHTML").ПолучитьТекст();
// Передаем текст в строковый реквизит формы, связанный с полем HTML
ЭтаФорма.РеквизитПолеHTML = ТекстHTML;
КонецПроцедуры
Рассмотрим подробнее важный нюанс: метод ПолучитьТекст() поддерживается только объектами макета с типами «Текстовый документ» или «HTML-документ».
Если макет был загружен как «Двоичные данные», попытка вызвать метод ПолучитьТекст() вызовет ошибку «Поле объекта не обнаружено (ПолучитьТекст)». В таком случае преобразование двоичных данных в строку HTML выполняется через функцию платформы:
&НаСервере
Процедура ЗагрузитьИзДвоичныхДанных()
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
ДвоичныеДанныеМакета = ОбработкаОбъект.ПолучитьМакет("МойМакетHTML");
ЭтаФорма.РеквизитПолеHTML = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанныеМакета, КодировкаТекста.UTF8);
КонецПроцедуры
Если форма создана как произвольная и не содержит основного реквизита Объект, метод РеквизитФормыВЗначение("Объект") использовать нельзя. В этой ситуации необходимо создать экземпляр внешней обработки через менеджер:
&НаСервере
Процедура ЗагрузитьМакетПроизвольнаяФорма(ПутьКФайлуОбработки)
// Создаем экземпляр обработки по пути к файлу
ЭкземплярОбработки = ВнешниеОбработки.Создать(ПутьКФайлуОбработки);
// Получаем макет у созданного объекта
ЭтаФорма.РеквизитПолеHTML = ЭкземплярОбработки.ПолучитьМакет("МойМакетHTML").ПолучитьТекст();
КонецПроцедуры
Проанализируем типичную проблему: если в HTML-макете прописаны относительные ссылки на картинки (например, <img src="logo.png">) или стили, браузер внутри поля 1С их не отобразит, так как у переданного текста нет базового URL-адреса. Для решения этой задачи используют следующие подходы:
Изображения кодируются непосредственно в HTML-код с помощью Data URL: <img src="data:image/png;base64,...">.
Картинки помещаются в макеты двоичных данных, выгружаются во временное хранилище на сервере, а в теги <img> подставляются ссылки вида e1cib/tempstorage/....
Если HTML-страница содержит сложную структуру файлов со скриптами и стилями, файлы распаковываются во временный каталог на клиенте, после чего вызывается метод клиентского элемента формы: Элементы.ПолеHTML.Перейти(ПолныйПутьКФайлу);.