Как получить макет внешней обработки из управляемой формы 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке внешних отчетов и обработок на платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с необходимостью сформировать печатную форму или выгрузить данные на основе макета, сохраненного внутри самой обработки. Однако при попытке получить макет из модуля управляемой формы стандартным методом частенько возникает досадная ошибка: «Недопустимое значение параметра (Параметр номер "1")».

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

Причина ошибки при использовании метода РеквизитФормыВЗначение

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

Типичный код на сервере выглядит следующим образом:


&НаСервере
Функция ПолучитьМакетНаСервере()
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    Макет = ОбработкаОбъект.ПолучитьМакет("ИмяМакет");
    Возврат Макет;
КонецФункции

Если при выполнении этого кода платформа выбрасывает ошибку недопустимого значения параметра, это означает, что функция РеквизитФормыВЗначение не смогла преобразовать реквизит формы в полноценный прикладной объект. Выясним причину этой проблемы. Чаще всего это происходит в двух случаях:

  1. Форма была скопирована из другой обработки или создана как произвольная. При копировании формы связь с ее «родным» объектом теряется. Реквизит формы Объект при этом может автоматически измениться на тип Строка или ссылаться на объект встроенной конфигурации, которого нет во внешней обработке.
  2. Реквизит не назначен основным. Чтобы система понимала, что форма напрямую связана с файлом обработки, реквизит Объект должен быть ведущим.

Решение 1: Правильная настройка реквизитов управляемой формы

Разберем по шагам, как исправить настройки реквизитов формы в конфигураторе, чтобы восстановить связь с объектом обработки:

  1. Откройте вашу внешнюю обработку в конфигураторе и перейдите в редактор управляемой формы.
  2. В правом верхнем окне перейдите на вкладку Реквизиты.
  3. Найдите реквизит с именем Объект. Если его нет, создайте его вручную.
  4. Откройте свойства этого реквизита и обратите внимание на строку Тип. Там должно быть строго указано: ВнешняяОбработкаОбъект.ИмяВашейОбработки (например, ВнешняяОбработкаОбъект.ПрайсЛистЛента). Ни в коем случае там не должно быть типа Строка или типа обработки из состава метаданных конфигурации.
  5. Нажмите правой кнопкой мыши на реквизит Объект и выберите пункт Установить как основной реквизит. Он выделится жирным шрифтом.

После выполнения этих простых настроек метод РеквизитФормыВЗначение("Объект") начнет отрабатывать корректно, предоставляя вам полный доступ к метаданным и макетам внешней обработки.

Решение 2: Динамическое определение пути к файлу обработки

Иногда программисты пытаются обойти проблему, инициализируя объект внешней обработки заново через метод ВнешниеОбработки.Создать(). Однако прописывание жесткого пути к файлу на диске вроде "C:\Users\Sadm\Desktop\Прайс-Лист.epf" крайне непрактично, ведь у конечного пользователя файл будет лежать в другом месте.

Выясним, как обойти это ограничение и получить путь к файлу динамически. У любого запущенного объекта внешней обработки есть полезное свойство ИспользуемоеИмяФайла. Рассмотрим пример кода, который позволяет пересоздать объект обработки без «хардкода» путей:


&НаСервере
Функция ПолучитьМакетДинамически()
    // Получаем текущий контекст нашей запущенной обработки
    ТекущийОбъект = РеквизитФормыВЗначение("Объект");
    
    // Определяем, откуда именно была запущена данная обработка
    ПутьКФайлу = ТекущийОбъект.ИспользуемоеИмяФайла; 
    
    // Инициализируем объект заново по динамическому пути
    НоваяОбработка = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь);
    Возврат НоваяОбработка.ПолучитьМакет("МакетПЛ");
КонецФункции

Важное примечание: Этот способ отлично подходит для локального тестирования или работы в файловом режиме, однако если обработка запускается в клиент-серверном варианте, сервер может не иметь доступа к локальному пути клиента.

Решение 3: Получение макета при интеграции с БСП

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

Для программного обращения к такой обработке и извлечения ее макета (например, из фонового задания или общего модуля) в БСП предусмотрен специальный программный интерфейс. Посмотрим на пример кода:


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

Этот способ является наиболее безопасным и современным для корпоративных информационных систем, работающих под управлением БСП.

Решение 4: Правильное распределение вызовов (Клиент-Сервер)

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


&НаКлиенте
Процедура СформироватьДокумент(Команда)
    // 1. Запускаем формирование печатной формы на сервере
    ТабличныйДокумент = СформироватьНаСервере();
    
    // 3. Возвращаем готовый результат на клиент и показываем пользователю
    Если ТабличныйДокумент <> Неопределено Тогда
        ТабличныйДокумент.Показать("Печать прайс-листа");
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция СформироватьНаСервере()
    // Получаем объект обработки (с учетом исправленного типа реквизита "Объект")
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Безопасно извлекаем макет
    Макет = ОбработкаОбъект.ПолучитьМакет("МакетПЛ");
    
    ТабДок = Новый ТабличныйДокумент;
    
    // Получаем область макета и заполняем её данными
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    ТабДок.Вывести(ОбластьШапка);
    
    // 2. Возвращаем сформированный табличный документ на клиент
    Возврат ТабДок;
КонецФункции

Используя этот паттерн проектирования совместно с корректно настроенным типом реквизита Объект, вы навсегда решите проблему получения любых макетов и двоичных данных из внешних обработок в управляемом интерфейсе 1С.

← На главную