В процессе разработки сложных интерфейсов в 1С часто возникает задача объединения функционала разных объектов на одном экране. Например, когда необходимо отобразить форму обработки внутри страницы другой формы, не прибегая к полному копированию кода и элементов. Рассмотрим подробнее, какими способами это можно реализовать, начиная от классических «обходных путей» и заканчивая современными штатными механизмами платформы.
Начиная с версии платформы 8.3.23, разработчики получили долгожданный инструмент — возможность прямого встраивания одной управляемой формы в другую. Это самый правильный и производительный метод на сегодняшний день. Разберем по шагам, как его реализовать.
Во-первых, проанализируем структуру основной формы. Для встраивания нам понадобится специальный реквизит. Создадим реквизит формы, например, с именем ВложеннаяФормаРеквизит и типом данных УправляемаяФорма.
Во-вторых, разместим этот реквизит на форме. При перетаскивании реквизита в дерево элементов формы, платформа автоматически предложит создать вид элемента Поле управляемой формы. Именно это поле будет служить контейнером для отображения сторонней формы.
В-третьих, нам необходимо программно инициализировать вложенную форму. Рассмотрим пример кода, который можно разместить в обработчике ПриСозданииНаСервере или в экспортном методе на клиенте:
&НаСервере
Процедура ИнициализироватьВложеннуюФормуНаСервере()
// Получаем форму нужной нам обработки
ПараметрыФормы = Новый Структура("Ключ", Объект.Ссылка);
ФормаВложения = ПолучитьФорму("Обработка.МояДополнительнаяОбработка.Форма.ФормаСписка", ПараметрыФормы);
// Помещаем полученный объект формы в реквизит, связанный с элементом управления
ВложеннаяФормаРеквизит = ФормаВложения;
КонецПроцедуры
Этот метод позволяет форме-контейнеру и вложенной форме работать в рамках одного сеанса, что экономит лицензии и упрощает передачу данных. Мы можем обращаться к экспортным переменным и методам вложенной формы напрямую через реквизит.
Если ваша версия платформы ниже 8.3.23, можно воспользоваться методом через Поле HTML-документа. Суть метода заключается в том, чтобы отобразить внутри формы веб-клиент вашей же базы, открытый на определенной ссылке.
Рассмотрим алгоритм реализации этого метода:
Поле HTML-документа.{АдресБазы}/#e1cib/app/{ИмяОбъекта}.Форма.{ИмяФормы}.Посмотрим на пример формирования такой ссылки в коде:
&НаКлиенте
Процедура ОткрытьФормуЧерезHTML()
БазовыйURL = "http://server/my_base";
НавигационнаяСсылка = "e1cib/app/Обработка.ВнешняяОбработка.Форма";
// Устанавливаем адрес в поле HTML
Элементы.ПолеHTML.Текст = "<iframe src='" + БазовыйURL + "/#" + НавигационнаяСсылка + "' style='width:100%; height:100%; border:none;'></iframe>";
КонецПроцедуры
Важный нюанс: Этот способ имеет существенный недостаток — лицензирование. Каждое такое встраивание через HTML-поле фактически запускает новый сеанс пользователя (веб-клиент). Если в форме открыто 3 вложенных окна, система спишет 3 дополнительные лицензии 1С.
Также проанализируем ситуацию с безопасностью. Веб-сервер может блокировать отображение страницы в iFrame (заголовок X-Frame-Options). Для корректной работы потребуется настройка конфигурационного файла веб-сервера, чтобы разрешить встраивание страниц.
Иногда задача «форма внутри формы» продиктована желанием создать удобный рабочий стол (дашборд). В этом случае выясним, не проще ли использовать типовой механизм Начальной страницы. Платформа 1С позволяет выводить на начальную страницу сразу несколько форм в разных колонках.
Если же формы находятся в разных расширениях, мы можем использовать механизм расширения начальной страницы. Мы добавляем нужные формы обработок в расширение и настраиваем их отображение в составе рабочей области рабочего стола. Это наиболее стабильный вариант для продакшена, так как он поддерживается платформой «из коробки» и не создает проблем с обновлением конфигурации.
Независимо от выбранного способа, нам необходимо организовать взаимодействие между основной и вложенной формами. Разберем, как это сделать наиболее эффективно.
Для обмена сообщениями лучше всего использовать механизм Оповещений. Рассмотрим схему работы:
Оповестить("СобытиеВложеннойФормы", Данные);.ОбработкаОповещения.Проанализируем пример кода для основной формы:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "СобытиеВложеннойФормы" Тогда
// Обрабатываем данные из вложенной формы
ЗначениеИзПодформы = Параметр.Значение;
Сообщить("Данные получены: " + ЗначениеИзПодформы);
КонецЕсли;
КонецПроцедуры
Выбор метода зависит от ваших технических условий:
Использование подобных подходов позволяет создавать по-настоящему современные и эргономичные интерфейсы, превращая разрозненные обработки в единое и удобное рабочее пространство пользователя.