Разработка и Конфигурация · 14 мин
Как получить форму внешней обработки в 1С
Как получить и открыть форму внешней обработки в 1С: ПолучитьФорму, ОткрытьФорму, ЭтотОбъект, работа в толстом и тонком клиенте, частые ошибки и примеры кода.
Получение формы внешней обработки — одна из базовых задач при разработке на платформе 1С:Предприятие. Внешняя обработка (файл .epf) не хранится внутри конфигурации, поэтому платформа не может найти её форму по имени, как это происходит с объектами метаданных. Форму приходится получать либо через объект обработки, либо с помощью специальных методов, и способ зависит от режима работы: толстый клиент, тонкий клиент, управляемые или обычные формы.
Главная сложность в том, что внешняя обработка может быть открыта двумя принципиально разными способами: через «Файл → Открыть» (тогда она работает как временный объект) или через подключение в справочник «Дополнительные отчеты и обработки». В каждом случае контекст, из которого доступна форма, различается, и код, который работает в одном сценарии, может выдавать ошибку «Объект не найден» в другом.
Ниже разобраны рабочие приёмы для обоих поколений интерфейса: ПолучитьФорму() для обычных форм и ОткрытьФорму() / ПолучитьФорму() глобального контекста для управляемых. Примеры приведены так, чтобы их можно было перенести в свой модуль с минимальными правками.
Как устроено получение формы внешней обработки
У внешней обработки может быть несколько форм: основная и дополнительные (например, форма настроек или форма выбора параметров). Каждая форма хранится внутри файла .epf и доступна только через объект этой обработки. Платформа не регистрирует формы внешних обработок в дереве метаданных, поэтому обращение вида ОткрытьФорму("Обработка.МояОбработка.Форма.Форма") для внешнего файла не сработает — такого пути в конфигурации просто нет.
Поэтому существует два подхода. Первый — получить форму из самой обработки, когда код выполняется в её модуле объекта: здесь доступен ЭтотОбъект, и у него есть метод ПолучитьФорму(). Второй — открыть форму «снаружи», из другого кода: тогда нужно либо создать объект обработки через ВнешниеОбработки.Создать(), либо передать форме сведения о том, откуда её вызывают, через параметр владельца.
Получение формы внутри модуля самой обработки
Самый простой и надёжный сценарий — когда форма нужна в коде самой внешней обработки. В модуле объекта обработки доступен контекст ЭтотОбъект, и вызов выглядит так:
ФормаНастроек = ЭтотОбъект.ПолучитьФорму("ФормаНастроек");
ФормаНастроек.Открыть();
В тонком клиенте и веб-клиенте прямой вызов ПолучитьФорму() у объекта внешней обработки часто недоступен или ведёт себя иначе, поэтому в управляемом приложении принято использовать глобальный метод ОткрытьФорму() с указанием владельца. Платформа сама определит, что форма принадлежит внешней обработке, если владельцем выступает её форма:
&НаКлиенте
Процедура ОткрытьНастройки(Команда)
ОткрытьФорму("ВнешняяОбработка.ИмяОбработки.Форма.ФормаНастроек", , ЭтотОбъект);
КонецПроцедуры
Обратите внимание: строка вида «ВнешняяОбработка.ИмяОбработки...» работает только если обработка подключена через механизм дополнительных отчётов и обработок (БСП) и у неё известно имя. Для файла, открытого через «Файл → Открыть», такой путь не существует — там правильный способ описан в следующем разделе.
Открытие формы внешней обработки из внешнего кода
Управляемые формы (тонкий клиент)
Когда обработка открыта через «Файл → Открыть» и из её основной формы нужно открыть вторую форму той же обработки, используется приём с передачей ключа уникальности и владельца. Надёжный вариант — хранить в основной форме путь к файлу обработки и строить имя формы через него:
&НаКлиенте
Процедура ОткрытьДопФорму(Команда)
ОткрытьФорму(ИмяФормыОбработки("ФормаНастроек"), , ЭтотОбъект);
КонецПроцедуры
&НаСервере
Функция ИмяФормыОбработки(ИмяНужнойФормы)
Возврат ЭтотОбъект.ПолучитьФормуИмя(ИмяНужнойФормы);
КонецФункции
На практике чаще применяют другой подход: в модуле основной формы вычисляют базовое имя через ЭтотОбъект.ИмяФормы и подставляют нужное имя формы. Например, если ЭтотОбъект.ИмяФормы возвращает «ВнешняяОбработка.МояОбработка.Форма.ОсновнаяФорма», то имя второй формы получают заменой последнего сегмента:
&НаКлиенте
Процедура ОткрытьДопФорму(Команда)
БазовоеИмя = Лев(ЭтотОбъект.ИмяФормы,
СтрНайти(ЭтотОбъект.ИмяФормы, ".", НаправлениеПоиска.СКонца));
ОткрытьФорму(БазовоеИмя + "ФормаНастроек", , ЭтотОбъект);
КонецПроцедуры
Такой код одинаково хорошо работает и для файла, открытого вручную, и для обработки, подключённой через БСП, потому что опирается на реальное имя текущей формы, а не на жёстко прописанный путь.
Обычные формы (толстый клиент)
В обычном приложении всё проще: у объекта внешней обработки есть прямой метод ПолучитьФорму(). Из внешнего кода объект создаётся методом ВнешниеОбработки.Создать() с указанием полного пути к файлу:
Обработка = ВнешниеОбработки.Создать("C:\Обработки\МояОбработка.epf");
Форма = Обработка.ПолучитьФорму("ОсновнаяФорма");
Форма.Открыть();
Метод ПолучитьФорму() без параметра вернёт основную форму обработки, если она назначена в свойствах объекта. Если основная форма не задана, вызов без параметра вернёт ошибку — указывайте имя явно.
Сравнение способов
Подходит для обычных форм и серверного кода. Не работает на клиенте в управляемом приложении.
Универсальный вариант для управляемых форм: работает и для файла .epf, и для подключённой обработки.
Только толстый клиент, обычные формы. Требует права на чтение файла и корректного пути.
Передача параметров и получение результата из формы
Получить форму — половина задачи; обычно в неё нужно передать данные и получить результат обратно. В управляемых формах параметры передаются вторым аргументом ОткрытьФорму() в виде структуры, а результат возвращается через описание оповещения:
&НаКлиенте
Процедура ВыбратьНастройки(Команда)
ПараметрыФормы = Новый Структура("ТекущийПериод", ПериодОтчета);
Оповещение = Новый ОписаниеОповещения("ПослеВыбораНастроек", ЭтотОбъект);
ОткрытьФорму(БазовоеИмя + "ФормаНастроек", ПараметрыФормы,
ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораНастроек(Результат, ДопПараметры) Экспорт
Если Результат <> Неопределено Тогда
ПериодОтчета = Результат.ВыбранныйПериод;
КонецЕсли;
КонецПроцедуры
В открываемой форме переданные параметры доступны через объект Параметры в обработчике ПриСозданииНаСервере. Чтобы вернуть значение, форма вызывает Закрыть(Результат) — переданное значение попадёт в первый параметр процедуры оповещения.
В обычных формах результат обычно возвращают через экспортные переменные формы или через метод ОткрытьМодально(), который возвращает значение, переданное в Закрыть(). Модальное открытие в управляемом приложении считается устаревшим приёмом и в ряде режимов запрещено настройками конфигурации — используйте оповещения.
- 1Определите базовое имя формы через ЭтотОбъект.ИмяФормы в основной форме обработки
- 2Сформируйте полное имя нужной формы, заменив последний сегмент на её имя
- 3Подготовьте структуру параметров и описание оповещения о закрытии
- 4Вызовите ОткрытьФорму() с владельцем ЭтотОбъект и режимом блокировки окна владельца
- 5В открываемой форме прочитайте Параметры в ПриСозданииНаСервере и верните результат через Закрыть(Значение)
- 6Проверьте работу и при открытии через Файл → Открыть, и при подключении через дополнительные обработки
Особенности при подключении через дополнительные отчёты и обработки
Если обработка подключена через подсистему «Дополнительные отчеты и обработки» Библиотеки стандартных подсистем, она получает регистрационное имя, и её формы становятся доступны по пути вида ВнешняяОбработка.ИмяОбработки.Форма.ИмяФормы. Это имя формируется автоматически при регистрации и может отличаться от имени файла — уточнить его можно в отладчике, посмотрев значение ЭтотОбъект.ИмяФормы в открытой форме.
В этом режиме есть ещё один нюанс: обработка может запускаться в безопасном режиме, если это настроено в параметрах регистрации. В безопасном режиме недоступны операции с файловой системой, COM-объекты и некоторые другие возможности. Если ваша форма при ручном открытии работает, а при запуске из справочника дополнительных обработок падает с ошибкой доступа — первым делом проверьте признак безопасного режима в настройках подключения.
Для фонового выполнения длительных операций из формы внешней обработки в БСП используется механизм длительных операций, который требует, чтобы обработка корректно возвращала сведения о себе через экспортную функцию СведенияОВнешнейОбработке() в модуле объекта. Если эта функция отсутствует или возвращает неполные данные, обработка может не регистрироваться или открываться с ограничениями.
Типичные ошибки и способы их устранения
Ошибка «Объект не найден» при вызове ОткрытьФорму() почти всегда означает, что имя формы построено неверно: либо обработка открыта как файл и пути «ВнешняяОбработка.Имя...» не существует, либо имя формы указано с опечаткой. Диагностируйте проблему через вывод ЭтотОбъект.ИмяФормы в сообщение или отладчик — это покажет реальный префикс, от которого нужно строить имя.
Вторая частая проблема — «Метод объекта не обнаружен: ПолучитьФорму» в тонком клиенте. Это значит, что код пытается вызвать ПолучитьФорму() у объекта обработки на клиенте в управляемом приложении, где этот метод недоступен. Решение — перенести логику на ОткрытьФорму() с вычислением имени формы, как показано выше.
Третья типичная ситуация — форма открывается, но параметры в ней пустые. Причина обычно в том, что в открываемой форме не объявлены соответствующие ключи параметров или чтение выполняется не в ПриСозданииНаСервере, а в обработчике, где Параметры уже недоступны. Также проверьте, что имена ключей структуры параметров совпадают с тем, что читает форма.
Проверка результата и отладка
Быстрый способ убедиться, что форма получается корректно, — временно вывести служебное сообщение перед открытием. Это особенно полезно, когда обработка должна работать в обоих режимах подключения:
&НаКлиенте
Процедура ОткрытьДопФорму(Команда)
БазовоеИмя = Лев(ЭтотОбъект.ИмяФормы,
СтрНайти(ЭтотОбъект.ИмяФормы, ".", НаправлениеПоиска.СКонца));
Сообщить("Открываю форму: " + БазовоеИмя + "ФормаНастроек");
ОткрытьФорму(БазовоеИмя + "ФормаНастроек", , ЭтотОбъект);
КонецПроцедуры
Для глубокой отладки внешней обработки удобно открыть её файл в конфигураторе и запустить отладку через «Отладка → Подключение», предварительно запустив предприятие из того же конфигуратора. Точки останова в модуле формы внешней обработки срабатывают так же, как в обычной конфигурации, если файл обработки открыт в конфигураторе и совпадает с запущенным.
Как проверить результат
Совпадает с реальным именем формы в дереве обработки
Лишний или отсутствующий сегмент, неверный регистр букв
Форма открывается в обоих режимах
Работает только в одном режиме — имя построено жёстко
Значения видны в Параметры при создании формы
Параметры пустые — проверьте имена ключей структуры
Часто задаваемые вопросы
Чем ПолучитьФорму() отличается от ОткрытьФорму()?
ПолучитьФорму() возвращает объект формы, который можно программно настроить и затем открыть вызовом Открыть() — это подход обычных форм и серверного кода. ОткрытьФорму() сразу открывает форму по её имени и работает асинхронно через оповещения — это стандарт для управляемого приложения. В тонком клиенте ПолучитьФорму() у внешней обработки на клиенте недоступен.
Почему вызов ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.Форма1") выдаёт ошибку?
Такой путь существует только если обработка зарегистрирована в справочнике дополнительных отчётов и обработок и у неё есть регистрационное имя. Для файла, открытого через «Файл → Открыть», стройте имя формы от значения ЭтотОбъект.ИмяФормы текущей открытой формы — тогда код сработает в обоих сценариях.
Как открыть форму внешней обработки из другой внешней обработки?
В обычных формах — через ВнешниеОбработки.Создать(ПутьКФайлу) с последующим ПолучитьФорму(). В управляемых формах прямого метода нет: нужно либо передать путь к файлу и открыть обработку штатными средствами, либо объединить обе формы в одну обработку. Хранить пути к файлам в коде небезопасно — при переносе базы они перестанут совпадать.
Можно ли получить форму внешней обработки на сервере?
Да, в серверном контексте ЭтотОбъект.ПолучитьФорму(ИмяФормы) доступен, но полученная на сервере форма не может быть показана пользователю напрямую — интерфейс существует только на клиенте. Серверное получение формы используют редко, в основном для обращения к её данным в специфических сценариях. Для показа пользователю всегда применяйте ОткрытьФорму() на клиенте.
Что делать, если форма открывается, но падает с ошибкой «Недопустимая операция в безопасном режиме»?
Обработка запущена в безопасном режиме через механизм дополнительных обработок, а код формы пытается выполнить запрещённое действие: работу с файлами, COM, внешними компонентами. Либо уберите эти операции из кода, либо администратор должен отключить безопасный режим для этой обработки в настройках регистрации, оценив риски.
Как вернуть несколько значений из закрываемой формы?
Передайте в Закрыть() структуру с нужными ключами, например Закрыть(Новый Структура("Период, Склад", Период, Склад)). В процедуре оповещения первый параметр будет содержать эту структуру. Не забудьте обработать случай Результат = Неопределено — так платформа сообщает, что форму закрыли крестиком без выбора.
Что важно запомнить
В управляемых формах получайте форму внешней обработки через ОткрытьФорму() с именем, построенным от ЭтотОбъект.ИмяФормы, — это работает и для файла, и для подключённой обработки. В обычных формах используйте ПолучитьФорму() объекта обработки. Параметры передавайте структурой, результат получайте через описание оповещения, и всегда проверяйте оба режима подключения обработки.