Почему ПолучитьФорму возвращает Неопределено для внешней обработки и как это исправить?

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

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

Разбор причины: метод Создать() против Подключить()

Проанализируем поведение платформы при использовании метода ВнешниеОбработки.Создать(). Этот метод создает экземпляр объекта внешней обработки в оперативной памяти сервера. Мы можем обращаться к его реквизитам, вызывать экспортные методы модуля объекта, но для системы этот объект остается "анонимным" в глобальном контексте имен.

Когда мы вызываем глобальный метод ПолучитьФорму("ВнешняяОбработка.ИмяОбработки.Форма.ИмяФормы"), платформа ищет описание этой обработки в специальном внутреннем реестре подключенных внешних объектов. Если обработка была инициализирована через Создать(), она не попадает в этот реестр. Следовательно, менеджер форм не может сопоставить строковое имя с конкретным объектом в памяти, и результатом выполнения функции становится Неопределено.

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

Сравнение механизмов работы методов

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

Рассмотрим пример кода, который приводит к ошибке:


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

&НаКлиенте
Процедура ВыполнитьДействие()
    Имя = ИнициализироватьОбработку("C:\ExternalProcs\MyProc.epf");
    // Здесь будет Неопределено, так как платформа не знает, 
    // к какой именно внешней обработке относится имя "MyProc"
    Форма = ПолучитьФорму("ВнешняяОбработка." + Имя + ".Форма.ФормаНастроек");
КонецПроцедуры

Правильная реализация через метод Подключить()

Чтобы метод ПолучитьФорму работал корректно в Тонком клиенте, нам необходимо использовать метод Подключить(). Разберем по шагам, как это сделать:

  1. Помещаем файл внешней обработки во временное хранилище.
  2. Вызываем метод ВнешниеОбработки.Подключить(), передавая адрес хранилища и желаемое имя регистрации.
  3. Используем полученное имя для вызова формы.

Посмотрим на пример правильной реализации:


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

&НаКлиенте
Процедура ОткрытьФормуОбработки()
    // Предположим, файл уже в хранилище
    Имя = ПодключитьВнешнююОбработку(АдресФайла);
    // Теперь форма будет получена успешно
    Форма = ПолучитьФорму("ВнешняяОбработка." + Имя + ".Форма.ИмяФормы");
    Если Форма <> Неопределено Тогда
        Форма.Открыть();
    КонецЕсли;
КонецПроцедуры

Организация удобной отладки внешних обработок

Часто программисты используют внешние обработки для быстрой отладки кода без необходимости постоянного обновления конфигурации. Если ваша цель — подменять внутреннюю обработку внешней при наличии файла на диске, можно использовать "метод-обертку".

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

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

Альтернативный способ для Толстого клиента

Если вы работаете в режиме Толстого клиента (управляемое приложение), существует еще один способ получения формы, минуя глобальный метод ПолучитьФорму. У самого объекта внешней обработки, созданного через Создать(), есть метод ПолучитьФорму().

Рассмотрим этот вариант:


// Работает преимущественно в толстом клиенте или на сервере
ОбъектОбработки = ВнешниеОбработки.Создать(ПутьКФайлу);
Форма = ОбъектОбработки.ПолучитьФорму("ФормаНастроек");

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

Резюме

Мы выяснили, что причина возврата Неопределено кроется в отсутствии регистрации объекта в пространстве имен текущего сеанса. Для решения проблемы:

  1. Всегда используйте ВнешниеОбработки.Подключить(), если планируете обращаться к формам обработки через методы ПолучитьФорму или ОткрытьФорму в Тонком клиенте.
  2. Помните, что регистрация через Подключить действует только в рамках текущего сеанса пользователя.
  3. Для целей отладки используйте регистрацию с выключенным безопасным режимом, что позволит полноценно использовать точки останова в модулях внешней обработки.

Использование этих подходов позволит вам создавать гибкие и легко отлаживаемые механизмы расширения функциональности ваших систем на базе 1С:Предприятие.

← На главную