Можно ли динамически формировать главное меню в управляемых формах 1С?

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

При переходе с обычного приложения на управляемые формы многие разработчики сталкиваются с вопросом гибкой настройки интерфейса. В обычном приложении можно было легко создать произвольное дерево в справочнике или обработке, прикрепить форму к левой границе рабочего пространства и получить полностью динамическое меню. Выясним, возможно ли повторить такое поведение в управляемом интерфейсе (включая интерфейс «Такси»), с какими ограничениями платформы придется столкнуться и как реализовать удобную альтернативу.

Архитектурные ограничения управляемого командного интерфейса

Проанализируем, как устроен командный интерфейс в управляемом приложении. Главное меню, панель разделов, панель навигации и панель действий формируются платформой строго декларативно на этапе инициализации конфигурации. Состав элементов рассчитывается автоматически на основе трех составляющих:

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

В объектной модели встроенного языка 1С нет методов для прямого программного добавления кнопок или изменения порядка разделов в главном меню. Мы не можем вызвать объект вроде «ПанельРазделов.Элементы.Добавить()» в рантайме. Кроме того, в управляемых формах отсутствует программный механизм жесткого прикрепления (докинга) произвольной формы к границе окна, как это было в обычном интерфейсе.

Решение 1. Управление меню через параметрические функциональные опции

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

Разберем по шагам, как это реализовать:

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

Посмотрим на пример кода, выполняемого на клиенте при изменении настроек пользователя:


ПараметрыОпций = Новый Структура;
ПараметрыОпций.Вставить("ТекущийПрофильИнтерфейса", ИдентификаторПрофиля);
УстановитьПараметрыФункциональныхОпций(ПараметрыОпций);

// Принудительно перестраиваем командный интерфейс текущего сеанса
ОбновитьИнтерфейс();

Этот способ позволяет динамически менять доступность целых разделов и отдельных команд, оставаясь в рамках типового интерфейса 1С.

Решение 2. Создание собственного АРМ или навигационной формы

Если стандартного командного интерфейса недостаточно и требуется иерархическое меню произвольной структуры с сортировкой и расчетом статусов, лучшим решением будет вынос навигации в отдельную форму. Рассмотрим два основных варианта компоновки:

  1. Форма начальной страницы (рабочего стола): форма назначается на начальную страницу конфигурации. Пользователь видит ее сразу при входе, она всегда открыта в центральной рабочей области.
  2. Компактная кнопка вызова навигатора: в командный интерфейс выносится одна общая команда (например, «Навигатор» или «Меню»), по нажатию на которую открывается форма выбора нужного рабочего места.

Чтобы стандартное меню не дублировало элементы и не перегружало экран, стандартные панели можно скрыть программно. Для этого используется объект НастройкиИнтерфейсаКлиентскогоПриложения с сохранением в системное хранилище настроек:


// Программная настройка состава панелей интерфейса
НастройкиИнтерфейса = Новый НастройкиИнтерфейсаКлиентскогоПриложения;
// Отключаем лишние стандартные панели
НастройкиИнтерфейса.ПанельРазделов.Видимость = Ложь;
НастройкиИнтерфейса.ПанельФункцийТекущегоРаздела.Видимость = Ложь;

ХранилищеСистемныхНастроек.Сохранить(
    "Общее/НастройкиИнтерфейсаКлиентскогоПриложения",
    "",
    НастройкиИнтерфейса
);

ОбновитьИнтерфейс();

Способы построения динамического меню внутри формы

После создания формы-навигатора выберем механизм динамического вывода элементов:

Вариант А: Иерархическое дерево значений или таблица формы

Создаем реквизит формы с типом ДеревоЗначений. В него загружаются разделы из справочника, регистра сведений или структуры прав. В событии таблицы Выбор вызываем нужный объект:


&НаКлиенте
Процедура МенюВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ТекущиеДанные = Элемент.ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено И ЗначениеЗаполнено(ТекущиеДанные.ИмяФормы) Тогда
        ОткрытьФорму(ТекущиеДанные.ИмяФормы);
    ИначеЕсли ЗначениеЗаполнено(ТекущиеДанные.НавигационнаяСсылка) Тогда
        ПерейтиПоНавигационнойСсылке(ТекущиеДанные.НавигационнаяСсылка);
    КонецЕсли;
КонецПроцедуры

Вариант Б: Программная генерация кнопок и групп формы

В событии ПриСозданииНаСервере мы можем полностью программно заполнить форму кнопками на основе прав или персональных настроек текущего пользователя:


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

Вариант В: Поле HTML-документа

Для создания современного интерфейса с анимациями, раскрывающимися списками и нестандартной версткой разместим на форме элемент с видом ПолеHTMLДокумента. В него генерируется готовая HTML/CSS-разметка. При клике по пунктам меню навигация перехватывается стандартными ссылками вида e1c: либо через событие ПриНажатии поля HTML.

Таким образом, прямое изменение глобального меню платформы невозможно из-за декларативной архитектуры управляемого приложения. Однако поставленная задача легко решается скрытием стандартных панелей и созданием собственной навигационной формы на начальной странице или в виде отдельного АРМ.

← На главную