Как открыть форму внешней обработки или отчета по навигационной ссылке (URL) в 1С 8.3 Управляемых Формах без регистрации в конфигурации?

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

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

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

Проблема прямого открытия внешних форм по ссылке

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

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

Решение: Использование Общей Формы в качестве посредника

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

Рассмотрим этот процесс по шагам.

Шаг 1: Создание Общей Формы-Посредника

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

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

Шаг 2: Реализация логики загрузки и открытия внешней формы в Общей Форме

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

Мы будем использовать обработчик события ПриСозданииНаСервере для этой общей формы. В этом обработчике мы выполним следующие действия:

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

Рассмотрим пример кода для Общей Формы:


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

            // Пример: Загрузка из макета общей формы (если обработка встроена в конфигурацию как макет)
            // ИмяМакета = Параметры.ИмяВнешнейОбработки; // Например, "МакетВнешнейОбработки1"
            // ДвоичныеДанные = ПолучитьМакет(ИмяМакета).ПолучитьДвоичныеДанные();
            // ВременныйФайл = ПолучитьИмяВременногоФайла(".epf");
            // ДвоичныеДанные.Записать(ВременныйФайл);
            // ПутьКВнешнейОбработке = ВременныйФайл;

            // Пример: Если в параметре ИмяВнешнейОбработки приходит путь к файлу на сервере
            ПутьКВнешнейОбработке = Параметры.ИмяВнешнейОбработки;

            // 2. Получаем менеджер внешней обработки/отчета.
            // Используем ВнешниеОбработки или ВнешниеОтчеты в зависимости от типа.
            МенеджерВнешнейОбработки = ВнешниеОбработки.ПолучитьМенеджерВнешнейОбработки(ПутьКВнешнейОбработке);
            // Если это отчет, используйте:
            // МенеджерВнешнегоОтчета = ВнешниеОтчеты.ПолучитьМенеджерВнешнегоОтчета(ПутьКВнешнейОбработке);

            // 3. Получаем форму внешней обработки.
            // Важно: вторым параметром мы можем передать параметры во внешнюю форму.
            // Мы передаем все параметры, которые пришли в общую форму, чтобы внешняя форма могла их использовать.
            ПараметрыДляВнешнейФормы = Новый Структура;
            Для Каждого КлючЗначение Из Параметры Цикл
                ПараметрыДляВнешнейФормы.Вставить(КлючЗначение.Ключ, КлючЗначение.Значение);
            КонецЦикла;
            
            // Если нужно передать только часть параметров, можно сформировать новую структуру:
            // ПараметрыДляВнешнейФормы.Вставить("ДополнительныйПараметр", Параметры.ДополнительныйПараметр);

            ФормаВнешнейОбработки = МенеджерВнешнейОбработки.ПолучитьФорму(
                Параметры.ИмяФормыВнешнейОбработки,
                ПараметрыДляВнешнейФормы // Передаем параметры во внешнюю форму
            );

            Если ФормаВнешнейОбработки <> Неопределено Тогда
                // 4. Открываем форму внешней обработки.
                // Она откроется как дочернее окно или новое окно в зависимости от настроек.
                ОткрытьФорму(ФормаВнешнейОбработки);

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

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

Важные моменты при загрузке внешней обработки:

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

Пример кода для внешней обработки/отчета, демонстрирующий получение переданных параметров:


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

Шаг 3: Формирование и вызов навигационной ссылки

Теперь, когда у нас есть общая форма, способная открывать внешние обработки, мы можем формировать навигационную ссылку, которая будет указывать на эту общую форму, а также содержать параметры для нашей внешней обработки.

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

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


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

&НаКлиенте
Процедура ОткрытьВнешнююФормуПоСсылке(Команда)
    // 1. Создаем структуру с параметрами, которые будут переданы в общую форму-посредник.
    // Эти параметры затем будут переданы и во внешнюю форму.
    ПараметрыДляОткрытия = Новый Структура;
    
    // Имя внешней обработки: может быть полным путем к файлу на сервере,
    // или именем макета в конфигурации, где хранится двоичные данные обработки.
    // Для демонстрации возьмем гипотетический путь.
    ПараметрыДляОткрытия.Вставить("ИмяВнешнейОбработки", "C:\MyExternalForms\MyProcessing.epf");
    // Или, если обработка хранится в макете общей формы-посредника:
    // ПараметрыДляОткрытия.Вставить("ИмяВнешнейОбработки", "МакетВнешнейОбработкиВОбщейФорме"); 
    
    // Имя формы, которую нужно открыть во внешней обработке (по умолчанию "Форма", но может быть и другая).
    ПараметрыДляОткрытия.Вставить("ИмяФормыВнешнейОбработки", "ФормаОсновная");
    
    // Дополнительные параметры, которые мы хотим передать во внешнюю форму.
    // Например, ссылка на какой-то объект или значение фильтра.
    ПараметрыДляОткрытия.Вставить("ДополнительныйПараметр", "ЗначениеПараметраИзНавигационнойСсылки");
    ПараметрыДляОткрытия.Вставить("ИдентификаторОбъекта", Новый УникальныйИдентификатор("d1f2e3c4-a5b6-7890-1234-567890abcdef"));
    
    // 2. Формируем навигационную ссылку на нашу общую форму, передавая в нее параметры.
    // Параметры будут сериализованы и добавлены к URL-строке.
    НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Объект, "ОбщаяФорма.МояОбщаяФормаДляВнешнихОбработок", ПараметрыДляОткрытия);
    
    // Пример сгенерированной ссылки (будет выглядеть примерно так, но в одну строку):
    // e1c://ОбщаяФорма.МояОбщаяФормаДляВнешнихОбработок?
    // ИмяВнешнейОбработки=C%3A%5CMyExternalForms%5CMyProcessing.epf
    // &ИмяФормыВнешнейОбработки=ФормаОсновная
    // &ДополнительныйПараметр=ЗначениеПараметраИзНавигационнойСсылки
    // &ИдентификаторОбъекта=d1f2e3c4-a5b6-7890-1234-567890abcdef
    
    // 3. Открываем общую форму по сформированной ссылке.
    // Система 1С автоматически обработает эту ссылку, откроет общую форму
    // и передаст ей все параметры, закодированные в URL.
    ОткрытьФормуПоСсылке(НавигационнаяСсылка);
КонецПроцедуры

Важно понимать: Функция ПолучитьНавигационнуюСсылку() автоматически кодирует параметры в URL-формат, а затем ОткрытьФормуПоСсылке() и механизм платформы 1С автоматически десериализуют их обратно в структуру Параметры в обработчике ПриСозданииНаСервере целевой формы.

Альтернативный подход: Встраивание формы внешней обработки

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

Для этого нам потребуется добавить на общую форму элемент управления типа "Панель" (например, с именем ПанельДляВстраивания), в которую мы будем встраивать форму внешней обработки. Изменения в коде Общей Формы будут выглядеть так:


// В модуле формы ОбщейФормы.МояОбщаяФормаДляВнешнихОбработок
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // ... (логика загрузки внешней обработки и получения ФормаВнешнейОбработки, как описано выше) ...

    Если ФормаВнешнейОбработки <> Неопределено Тогда
        // Вместо ОткрытьФорму(ФормаВнешнейОбработки) используем ВставитьФорму()
        Если ЭтаФорма.Элементы.Найти("ПанельДляВстраивания") <> Неопределено Тогда
            ЭтаФорма.Элементы.ПанельДляВстраивания.ВставитьФорму(ФормаВнешнейОбработки);
        Иначе
            Сообщить("На форме отсутствует элемент 'ПанельДляВстраивания'. Форма внешней обработки не может быть встроена.", СтатусСообщения.Важное);
            ОткрытьФорму(ФормаВнешнейОбработки); // Открываем как отдельное окно
        КонецЕсли;
    Иначе
        // ... (обработка ошибки) ...
    КонецЕсли;
    // ...
КонецПроцедура

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

Заключение

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

Этот подход позволяет нам:

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

← На главную