К статье
Практический материал

Разработка и Конфигурация · 14 мин

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

Как получить и открыть форму внешней обработки в 1С: ПолучитьФорму, ОткрытьФорму, ЭтотОбъект, работа в толстом и тонком клиенте, частые ошибки и примеры кода.

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

Главная сложность в том, что внешняя обработка может быть открыта двумя принципиально разными способами: через «Файл → Открыть» (тогда она работает как временный объект) или через подключение в справочник «Дополнительные отчеты и обработки». В каждом случае контекст, из которого доступна форма, различается, и код, который работает в одном сценарии, может выдавать ошибку «Объект не найден» в другом.

Ниже разобраны рабочие приёмы для обоих поколений интерфейса: ПолучитьФорму() для обычных форм и ОткрытьФорму() / ПолучитьФорму() глобального контекста для управляемых. Примеры приведены так, чтобы их можно было перенести в свой модуль с минимальными правками.

Как устроено получение формы внешней обработки

У внешней обработки может быть несколько форм: основная и дополнительные (например, форма настроек или форма выбора параметров). Каждая форма хранится внутри файла .epf и доступна только через объект этой обработки. Платформа не регистрирует формы внешних обработок в дереве метаданных, поэтому обращение вида ОткрытьФорму("Обработка.МояОбработка.Форма.Форма") для внешнего файла не сработает — такого пути в конфигурации просто нет.

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

Получение формы внутри модуля самой обработки

Самый простой и надёжный сценарий — когда форма нужна в коде самой внешней обработки. В модуле объекта обработки доступен контекст ЭтотОбъект, и вызов выглядит так:

ФормаНастроек = ЭтотОбъект.ПолучитьФорму("ФормаНастроек");

ФормаНастроек.Открыть();

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

&НаКлиенте

Процедура ОткрытьНастройки(Команда)

ОткрытьФорму("ВнешняяОбработка.ИмяОбработки.Форма.ФормаНастроек", , ЭтотОбъект);

КонецПроцедуры

Обратите внимание: строка вида «ВнешняяОбработка.ИмяОбработки...» работает только если обработка подключена через механизм дополнительных отчётов и обработок (БСП) и у неё известно имя. Для файла, открытого через «Файл → Открыть», такой путь не существует — там правильный способ описан в следующем разделе.

Открытие формы внешней обработки из внешнего кода

Управляемые формы (тонкий клиент)

Когда обработка открыта через «Файл → Открыть» и из её основной формы нужно открыть вторую форму той же обработки, используется приём с передачей ключа уникальности и владельца. Надёжный вариант — хранить в основной форме путь к файлу обработки и строить имя формы через него:

&НаКлиенте

Процедура ОткрытьДопФорму(Команда)

ОткрытьФорму(ИмяФормыОбработки("ФормаНастроек"), , ЭтотОбъект);

КонецПроцедуры

&НаСервере

Функция ИмяФормыОбработки(ИмяНужнойФормы)

Возврат ЭтотОбъект.ПолучитьФормуИмя(ИмяНужнойФормы);

КонецФункции

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

&НаКлиенте

Процедура ОткрытьДопФорму(Команда)

БазовоеИмя = Лев(ЭтотОбъект.ИмяФормы,

СтрНайти(ЭтотОбъект.ИмяФормы, ".", НаправлениеПоиска.СКонца));

ОткрытьФорму(БазовоеИмя + "ФормаНастроек", , ЭтотОбъект);

КонецПроцедуры

Такой код одинаково хорошо работает и для файла, открытого вручную, и для обработки, подключённой через БСП, потому что опирается на реальное имя текущей формы, а не на жёстко прописанный путь.

Обычные формы (толстый клиент)

В обычном приложении всё проще: у объекта внешней обработки есть прямой метод ПолучитьФорму(). Из внешнего кода объект создаётся методом ВнешниеОбработки.Создать() с указанием полного пути к файлу:

Обработка = ВнешниеОбработки.Создать("C:\Обработки\МояОбработка.epf");

Форма = Обработка.ПолучитьФорму("ОсновнаяФорма");

Форма.Открыть();

Метод ПолучитьФорму() без параметра вернёт основную форму обработки, если она назначена в свойствах объекта. Если основная форма не задана, вызов без параметра вернёт ошибку — указывайте имя явно.

Сравнение способов

ЭтотОбъект.ПолучитьФорму() в модуле объекта

Подходит для обычных форм и серверного кода. Не работает на клиенте в управляемом приложении.

ОткрытьФорму() с именем через ЭтотОбъект.ИмяФормы

Универсальный вариант для управляемых форм: работает и для файла .epf, и для подключённой обработки.

ВнешниеОбработки.Создать() + ПолучитьФорму()

Только толстый клиент, обычные формы. Требует права на чтение файла и корректного пути.

Передача параметров и получение результата из формы

Получить форму — половина задачи; обычно в неё нужно передать данные и получить результат обратно. В управляемых формах параметры передаются вторым аргументом ОткрытьФорму() в виде структуры, а результат возвращается через описание оповещения:

&НаКлиенте

Процедура ВыбратьНастройки(Команда)

ПараметрыФормы = Новый Структура("ТекущийПериод", ПериодОтчета);

Оповещение = Новый ОписаниеОповещения("ПослеВыбораНастроек", ЭтотОбъект);

ОткрытьФорму(БазовоеИмя + "ФормаНастроек", ПараметрыФормы,

ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

КонецПроцедуры

&НаКлиенте

Процедура ПослеВыбораНастроек(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

ПериодОтчета = Результат.ВыбранныйПериод;

КонецЕсли;

КонецПроцедуры

В открываемой форме переданные параметры доступны через объект Параметры в обработчике ПриСозданииНаСервере. Чтобы вернуть значение, форма вызывает Закрыть(Результат) — переданное значение попадёт в первый параметр процедуры оповещения.

В обычных формах результат обычно возвращают через экспортные переменные формы или через метод ОткрытьМодально(), который возвращает значение, переданное в Закрыть(). Модальное открытие в управляемом приложении считается устаревшим приёмом и в ряде режимов запрещено настройками конфигурации — используйте оповещения.

Порядок действий для управляемых форм
  1. 1
    Определите базовое имя формы через ЭтотОбъект.ИмяФормы в основной форме обработки
  2. 2
    Сформируйте полное имя нужной формы, заменив последний сегмент на её имя
  3. 3
    Подготовьте структуру параметров и описание оповещения о закрытии
  4. 4
    Вызовите ОткрытьФорму() с владельцем ЭтотОбъект и режимом блокировки окна владельца
  5. 5
    В открываемой форме прочитайте Параметры в ПриСозданииНаСервере и верните результат через Закрыть(Значение)
  6. 6
    Проверьте работу и при открытии через Файл → Открыть, и при подключении через дополнительные обработки

Особенности при подключении через дополнительные отчёты и обработки

Если обработка подключена через подсистему «Дополнительные отчеты и обработки» Библиотеки стандартных подсистем, она получает регистрационное имя, и её формы становятся доступны по пути вида ВнешняяОбработка.ИмяОбработки.Форма.ИмяФормы. Это имя формируется автоматически при регистрации и может отличаться от имени файла — уточнить его можно в отладчике, посмотрев значение ЭтотОбъект.ИмяФормы в открытой форме.

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

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

Типичные ошибки и способы их устранения

Ошибка «Объект не найден» при вызове ОткрытьФорму() почти всегда означает, что имя формы построено неверно: либо обработка открыта как файл и пути «ВнешняяОбработка.Имя...» не существует, либо имя формы указано с опечаткой. Диагностируйте проблему через вывод ЭтотОбъект.ИмяФормы в сообщение или отладчик — это покажет реальный префикс, от которого нужно строить имя.

Вторая частая проблема — «Метод объекта не обнаружен: ПолучитьФорму» в тонком клиенте. Это значит, что код пытается вызвать ПолучитьФорму() у объекта обработки на клиенте в управляемом приложении, где этот метод недоступен. Решение — перенести логику на ОткрытьФорму() с вычислением имени формы, как показано выше.

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

Типичные ошибки
01
Жёстко прописанный путь вида ВнешняяОбработка.Имя — ломается при открытии файла вручную; используйте ЭтотОбъект.ИмяФормы как основу
02
Вызов ПолучитьФорму() на клиенте в управляемом приложении — метод недоступен, замените на ОткрытьФорму()
03
Несовпадение имён параметров между вызывающей и открываемой формой — параметры молча теряются
04
Открытие модальной формы в конфигурации с запрещёнными модальными вызовами — код не выполняется, используйте описания оповещений

Проверка результата и отладка

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

&НаКлиенте

Процедура ОткрытьДопФорму(Команда)

БазовоеИмя = Лев(ЭтотОбъект.ИмяФормы,

СтрНайти(ЭтотОбъект.ИмяФормы, ".", НаправлениеПоиска.СКонца));

Сообщить("Открываю форму: " + БазовоеИмя + "ФормаНастроек");

ОткрытьФорму(БазовоеИмя + "ФормаНастроек", , ЭтотОбъект);

КонецПроцедуры

Для глубокой отладки внешней обработки удобно открыть её файл в конфигураторе и запустить отладку через «Отладка → Подключение», предварительно запустив предприятие из того же конфигуратора. Точки останова в модуле формы внешней обработки срабатывают так же, как в обычной конфигурации, если файл обработки открыт в конфигураторе и совпадает с запущенным.

Контрольные точки

Как проверить результат

Имя формы в сообщении или отладчике
Норма

Совпадает с реальным именем формы в дереве обработки

Тревожный признак

Лишний или отсутствующий сегмент, неверный регистр букв

Открытие из файла и из доп. обработок
Норма

Форма открывается в обоих режимах

Тревожный признак

Работает только в одном режиме — имя построено жёстко

Передача параметров
Норма

Значения видны в Параметры при создании формы

Тревожный признак

Параметры пустые — проверьте имена ключей структуры

Часто задаваемые вопросы

Чем ПолучитьФорму() отличается от ОткрытьФорму()?

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

Почему вызов ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.Форма1") выдаёт ошибку?

Такой путь существует только если обработка зарегистрирована в справочнике дополнительных отчётов и обработок и у неё есть регистрационное имя. Для файла, открытого через «Файл → Открыть», стройте имя формы от значения ЭтотОбъект.ИмяФормы текущей открытой формы — тогда код сработает в обоих сценариях.

Как открыть форму внешней обработки из другой внешней обработки?

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

Можно ли получить форму внешней обработки на сервере?

Да, в серверном контексте ЭтотОбъект.ПолучитьФорму(ИмяФормы) доступен, но полученная на сервере форма не может быть показана пользователю напрямую — интерфейс существует только на клиенте. Серверное получение формы используют редко, в основном для обращения к её данным в специфических сценариях. Для показа пользователю всегда применяйте ОткрытьФорму() на клиенте.

Что делать, если форма открывается, но падает с ошибкой «Недопустимая операция в безопасном режиме»?

Обработка запущена в безопасном режиме через механизм дополнительных обработок, а код формы пытается выполнить запрещённое действие: работу с файлами, COM, внешними компонентами. Либо уберите эти операции из кода, либо администратор должен отключить безопасный режим для этой обработки в настройках регистрации, оценив риски.

Как вернуть несколько значений из закрываемой формы?

Передайте в Закрыть() структуру с нужными ключами, например Закрыть(Новый Структура("Период, Склад", Период, Склад)). В процедуре оповещения первый параметр будет содержать эту структуру. Не забудьте обработать случай Результат = Неопределено — так платформа сообщает, что форму закрыли крестиком без выбора.

Итог

Что важно запомнить

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