Как в пользовательском режиме 1С реализовать выбор подсистем из конфигурации?

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

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

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

Использование общей формы «ВыборОбъектовМетаданных»

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

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

Для начала подготовим параметры выбора и настроим фильтр так, чтобы в окне отображались только подсистемы. Рассмотрим пример кода:


// Определим массив имен метаданных, которые мы хотим видеть в списке выбора
ОтборПодсистем = Новый Массив;
ОтборПодсистем.Добавить("Подсистемы");

// Подготавливаем параметры через стандартный метод БСП
ПараметрыВыбора = СтандартныеПодсистемыКлиентСервер.ПараметрыВыбораОбъектовМетаданных();
ПараметрыВыбора.ФильтрПоОбъектамМетаданных = ОтборПодсистем;
ПараметрыВыбора.МножественныйВыбор = Истина;
ПараметрыВыбора.Заголовок = "Выберите подсистемы для анализа";

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

// Вызываем форму выбора
СтандартныеПодсистемыКлиент.ВыбратьОбъектыМетаданных(ПараметрыВыбора, ОписаниеОповещения);

В данном примере мы устанавливаем свойство ФильтрПоОбъектамМетаданных, передавая туда массив со строкой "Подсистемы". Это заставляет форму скрыть справочники, документы и прочие объекты, оставив только дерево подсистем.

Настройка параметров окна выбора

Проанализируем структуру ПараметрыВыбораОбъектовМетаданных подробнее, чтобы понять, как сделать интерфейс еще удобнее:

  1. Множественный выбор: Установив ПараметрыВыбора.МножественныйВыбор = Истина, мы позволяем пользователю отметить сразу несколько подсистем флажками.
  2. Выбор корневых объектов: Свойство РазрешитьВыборКорневыхОбъектов позволяет разрешить или запретить выбор родительских подсистем (узлов дерева).
  3. Заголовок: Мы можем задать осмысленный текст в шапке окна, чтобы пользователь понимал контекст операции.

После того как пользователь нажмет кнопку «Выбрать», управление передается в процедуру обработки, которую мы указали в ОписаниеОповещения. Выясним, как правильно обработать результат:


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

Альтернатива: Справочник «Идентификаторы объектов метаданных»

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

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


ПараметрыФормы = Новый Структура;
ФиксированныеНастройки = Новый НастройкиКомпоновкиДанных;
ЭлементОтбора = ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ИмяТипа");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = "Подсистема";
ЭлементОтбора.Использование = Истина;

ПараметрыФормы.Вставить("ФиксированныеНастройки", ФиксированныеНастройки);

ОткрытьФорму("Справочник.ИдентификаторыОбъектовМетаданных.ФормаВыбора", ПараметрыФормы, ЭтотОбъект);

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

Как получить состав выбранной подсистемы?

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

Посмотрим на пример получения состава подсистемы на сервере:


ИмяПодсистемы = "Продажи"; // Без префикса "Подсистема."
МассивОбъектов = ОбщегоНазначения.СоставПодсистемы(ИмяПодсистемы);

Для Каждого ИмяОбъекта Из МассивОбъектов Цикл
    // ИмяОбъекта будет иметь вид "Документ.РеализацияТоваровУслуг"
    Сообщить("В подсистему входит объект: " + ИмяОбъекта);
КонецЦикла;

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

Создание собственного дерева выбора подсистем

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

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

Пример рекурсивной функции для заполнения дерева:


&НаСервере
Процедура ЗаполнитьДеревоПодсистем(УзелДерева, КоллекцияМетаданных)
    
    Для Каждого ПодсистемаМетаданные Из КоллекцияМетаданных Цикл
        НоваяСтрока = УзелДерева.ПолучитьЭлементы().Добавить();
        НоваяСтрока.Наименование = ПодсистемаМетаданные.Представление();
        НоваяСтрока.ИмяПолное = ПодсистемаМетаданные.ПолноеИмя();
        
        // Рекурсивно заходим во вложенные подсистемы
        ЗаполнитьДеревоПодсистем(НоваяСтрока, ПодсистемаМетаданные.Подсистемы);
    КонецЦикла;
    
КонецПроцедуры

Вызов этой процедуры для корня конфигурации будет выглядеть так: ЗаполнитьДеревоПодсистем(ДеревоНаФорме, Метаданные.Подсистемы);.

Важное замечание о «живых» метаданных

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

В типовых конфигурациях обновление идентификаторов происходит автоматически при запуске после обновления версии программы. Однако при разработке или в специфических сценариях может потребоваться принудительное обновление. Для этого используйте метод:

Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника();

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

← На главную