Как реализовать выбор нескольких ролей из списка в отчете СКД с внешним набором данных

Программист IT и автоматизация бизнеса
← На главную

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

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

Шаг 1. Настройка параметров в схеме компоновки данных

Прежде всего, нам необходимо подготовить саму схему (макет СКД). Разберем по шагам, что нужно сделать на закладке Параметры:

  1. Создадим новый параметр, назовем его, например, СписокВыбранныхРолей.
  2. Установим тип данных — Строка (так как наименования ролей в платформе представлены строками).
  3. Важный момент: установим флаг Доступен список значений. Это позволит пользователю в окне настроек выбирать несколько элементов (операция "В списке").
  4. В колонке "Ограничение доступности" флаг ставить не нужно, если мы хотим, чтобы пользователь видел этот параметр.

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

Шаг 2. Программное заполнение списка доступных значений

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

Проанализируем пример кода, который позволяет динамически считать все роли из метаданных и подставить их в доступные значения параметра СКД:


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

Этот код лучше всего вызвать в процедуре ПриКомпоновкеРезультата или при открытии формы отчета. Обратите внимание на использование метода УстановитьДоступныеЗначения — именно он отвечает за то, что при нажатии на "три точки" в поле параметра пользователь увидит аккуратный список всех ролей вашей базы.

Шаг 3. Работа с внешним набором данных (объектом)

Теперь выясним, как связать выбранные пользователем роли с данными, которые мы передаем в СКД. Автор темы использует Таблицу Значений как внешний источник. Здесь есть два пути: фильтровать таблицу до передачи в СКД или позволить СКД фильтровать её после получения.

Вариант А: Фильтрация в коде (рекомендуется для производительности).

Рассмотрим, как получить выбранные пользователем значения из компоновщика настроек и использовать их при заполнении таблицы значений:


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

    // Формируем таблицу значений
    ТЗ_Данные = Новый ТаблицаЗначений;
    ТЗ_Данные.Колонки.Добавить("Пользователь", Новый ОписаниеТипов("СправочникСсылка.Пользователи"));
    ТЗ_Данные.Колонки.Добавить("Роль", Новый ОписаниеТипов("Строка"));

    СписокПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Для каждого ПользовательИБ Из СписокПользователей Цикл
        Для каждого РольИБ Из ПользовательИБ.Роли Цикл
            // Если фильтр пустой - берем всё, иначе проверяем вхождение
            Если ВыбранныеРоли.Количество() = 0 Или ВыбранныеРоли.Найти(РольИБ.Имя) <> Неопределено Тогда
                НоваяСтрока = ТЗ_Данные.Добавить();
                НоваяСтрока.Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ПользовательИБ.ПолноеИмя);
                НоваяСтрока.Роль = РольИБ.Имя;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

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

Шаг 4. Использование стандартных отборов СКД

Если вы не хотите фильтровать таблицу вручную, можно настроить поле "Роль" в наборе данных так, чтобы СКД само применяло к нему фильтр. В этом случае в настройках отчета на закладке Отбор пользователь сможет добавить поле "Роль" и выбрать вид сравнения "В списке".

Однако, чтобы пользователь не вписывал роли руками, нам все равно потребуется прием из Шага 2, но примененный не к параметру, а к полю набора данных. В схеме компоновки для поля "Роль" можно указать список доступных значений аналогичным способом через СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Найти("Роль").

Особенности реализации на управляемых формах

Проанализируем ситуацию, если вы работаете в 1С 8.3 на управляемых формах. В этом случае код инициализации параметров лучше выносить в процедуру ПриСозданииНаСервере. Также важно помнить, что если параметр вынесен в "Быстрые настройки", то обращаться к нему нужно не через КомпоновщикНастроек.Настройки, а через КомпоновщикНастроек.ПользовательскиеНастройки.

Разберем типичную ошибку: программист заполняет ДоступныеЗначения в схеме, но забывает переинициализировать ИсточникДоступныхНастроекКомпоновкиДанных. Без этого действия форма отчета "не узнает", что список выбора обновился, и кнопка выбора по-прежнему будет открывать пустое окно.

Подводя итог, можно сказать, что связка Метаданные.Роли + УстановитьДоступныеЗначения() является самым гибким и правильным способом реализации подбора ролей в СКД. Это делает ваш отчет устойчивым к изменениям конфигурации и удобным для конечного пользователя.

← На главную