При разработке сложных отчетов в среде 1С часто возникает ситуация, когда стандартного запроса к базе данных недостаточно. Например, если нам нужно проанализировать права доступа и роли пользователей информационный базы, данные приходится получать программно через объект ПользователиИнформационнойБазы. В этом случае мы используем "Набор данных - объект" в Системе Компоновки Данных (СКД). Однако встает вопрос: как организовать удобный пользовательский отбор по этим ролям, чтобы можно было выбирать значения из списка, а не вводить их вручную строкой?
В данной статье мы подробно разберем, как настроить схему компоновки, программно заполнить список доступных ролей из метаданных и связать этот выбор с фильтрацией внешнего набора данных.
Прежде всего, нам необходимо подготовить саму схему (макет СКД). Разберем по шагам, что нужно сделать на закладке Параметры:
СписокВыбранныхРолей.Строка (так как наименования ролей в платформе представлены строками).На этом этапе параметр существует, но он пуст. Если пользователь нажмет кнопку выбора, он увидит пустое окно. Наша задача — наполнить его всеми ролями, которые существуют в конфигурации.
Поскольку состав ролей в конфигурации может меняться, жестко прописывать их в макете — плохое решение. Мы воспользуемся программной инициализацией. Рассмотрим ситуацию, когда мы работаем в модуле отчета или форме. Нам нужно перехватить момент перед формированием отчета.
Проанализируем пример кода, который позволяет динамически считать все роли из метаданных и подставить их в доступные значения параметра СКД:
Процедура ИнициализироватьСписокРолей()
// 1. Получаем все роли из конфигурации
СписокРолейКонфигурации = Новый СписокЗначений;
Для каждого МетаРоль Из Метаданные.Роли Цикл
// Добавляем Имя роли для логики и Синоним для представления пользователю
Представление = ?(ЗначениеЗаполнено(МетаРоль.Синоним), МетаРоль.Синоним, МетаРоль.Имя);
СписокРолейКонфигурации.Добавить(МетаРоль.Имя, Представление);
КонецЦикла;
// 2. Находим параметр в схеме компоновки
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("СписокВыбранныхРолей");
Если ПараметрСхемы <> Неопределено Тогда
// Устанавливаем список, который увидит пользователь при нажатии на кнопку выбора
ПараметрСхемы.УстановитьДоступныеЗначения(СписокРолейКонфигурации);
КонецЕсли;
// 3. Обновляем компоновщик настроек, чтобы изменения вступили в силу
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
КонецПроцедуры
Этот код лучше всего вызвать в процедуре ПриКомпоновкеРезультата или при открытии формы отчета. Обратите внимание на использование метода УстановитьДоступныеЗначения — именно он отвечает за то, что при нажатии на "три точки" в поле параметра пользователь увидит аккуратный список всех ролей вашей базы.
Теперь выясним, как связать выбранные пользователем роли с данными, которые мы передаем в СКД. Автор темы использует Таблицу Значений как внешний источник. Здесь есть два пути: фильтровать таблицу до передачи в СКД или позволить СКД фильтровать её после получения.
Вариант А: Фильтрация в коде (рекомендуется для производительности).
Рассмотрим, как получить выбранные пользователем значения из компоновщика настроек и использовать их при заполнении таблицы значений:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем значение параметра из пользовательских настроек
Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("СписокВыбранныхРолей"));
ВыбранныеРоли = Новый Массив;
Если Параметр <> Неопределено И Параметр.Использование Тогда
ВыбранныеРоли = Параметр.Значение.ВыгрузитьЗначения();
КонецЕсли;
// Формируем таблицу значений
ТЗ_Данные = Новый ТаблицаЗначений;
ТЗ_Данные.Колонки.Добавить("Пользователь", Новый ОписаниеТипов("СправочникСсылка.Пользователи"));
ТЗ_Данные.Колонки.Добавить("Роль", Новый ОписаниеТипов("Строка"));
СписокПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей();
Для каждого ПользовательИБ Из СписокПользователей Цикл
Для каждого РольИБ Из ПользовательИБ.Роли Цикл
// Если фильтр пустой - берем всё, иначе проверяем вхождение
Если ВыбранныеРоли.Количество() = 0 Или ВыбранныеРоли.Найти(РольИБ.Имя) <> Неопределено Тогда
НоваяСтрока = ТЗ_Данные.Добавить();
НоваяСтрока.Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ПользовательИБ.ПолноеИмя);
НоваяСтрока.Роль = РольИБ.Имя;
КонецЕсли;
КонецЦикла;
КонецЦикла;
// Передаем ТЗ во внешний набор данных
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТаблицаРолей", ТЗ_Данные);
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Если вы не хотите фильтровать таблицу вручную, можно настроить поле "Роль" в наборе данных так, чтобы СКД само применяло к нему фильтр. В этом случае в настройках отчета на закладке Отбор пользователь сможет добавить поле "Роль" и выбрать вид сравнения "В списке".
Однако, чтобы пользователь не вписывал роли руками, нам все равно потребуется прием из Шага 2, но примененный не к параметру, а к полю набора данных. В схеме компоновки для поля "Роль" можно указать список доступных значений аналогичным способом через СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Найти("Роль").
Проанализируем ситуацию, если вы работаете в 1С 8.3 на управляемых формах. В этом случае код инициализации параметров лучше выносить в процедуру ПриСозданииНаСервере. Также важно помнить, что если параметр вынесен в "Быстрые настройки", то обращаться к нему нужно не через КомпоновщикНастроек.Настройки, а через КомпоновщикНастроек.ПользовательскиеНастройки.
Разберем типичную ошибку: программист заполняет ДоступныеЗначения в схеме, но забывает переинициализировать ИсточникДоступныхНастроекКомпоновкиДанных. Без этого действия форма отчета "не узнает", что список выбора обновился, и кнопка выбора по-прежнему будет открывать пустое окно.
Подводя итог, можно сказать, что связка Метаданные.Роли + УстановитьДоступныеЗначения() является самым гибким и правильным способом реализации подбора ролей в СКД. Это делает ваш отчет устойчивым к изменениям конфигурации и удобным для конечного пользователя.