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