При разработке отчетов на базе системы компоновки данных (СКД) часто возникает задача ограничить данные отчета для конкретного пользователя или группы пользователей. Например, требуется, чтобы при открытии и формировании отчета значение отбора или параметра Организация автоматически заполнялось значением по умолчанию для текущего пользователя и было недоступно для редактирования в пользовательском интерфейсе (как на панели быстрых отборов, так и в расширенных настройках).
Рассмотрим несколько эффективных способов решения этой задачи: от использования стандартных возможностей схемы компоновки данных до тонкой программной настройки компоновщика на управляемых формах.
Наиболее корректным архитектурным подходом для управляемых форм является использование свойства ФиксированныеНастройки у объекта КомпоновщикНастроек. Фиксированные настройки применяются платформой поверх пользовательских настроек по логическому условию «И», при этом платформа автоматически исключает такие отборы из окна настроек и панели быстрых пользовательских отборов.
Разберем по шагам, как задать фиксированный отбор программно в модуле формы отчета:
ПриСозданииНаСервере.Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Посмотрим на пример реализации данного метода:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем текущего пользователя и его организацию
ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
СсылкаНаПользователя = Справочники.Пользователи.НайтиПоНаименованию(ТекущийПользователь.Имя);
Если ЗначениеЗаполнено(СсылкаНаПользователя) И ЗначениеЗаполнено(СсылкаНаПользователя.Организация) Тогда
// Очищаем существующие фиксированные отборы по полю Организация, если они были
ФиксированныйОтбор = Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор;
ЭлементОтбора = ФиксированныйОтбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = СсылкаНаПользователя.Организация;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Важное преимущество: фиксированные настройки не затираются при восстановлении стандартных или пользовательских вариантов отчета, а пользователю не требуется вручную следить за их корректностью.
Если условие фильтрации заложено на уровне параметров запроса в схеме компоновки данных, мы можем ограничить его редактирование без написания кода в форме.
Проанализируем шаги настройки в схеме компоновки данных:
Организация (или создадим его, если фильтрация выполняется в запросе через ГДЕ Организация = &Организация).ОбщегоНазначения.ПолучитьОрганизациюПоУмолчанию().В этом случае платформа автоматически при компоновке результата вычислит значение параметра и применит его к выборке данных.
В случаях, когда отчет формируется без использования стандартной формы или требуется гарантировать применение отбора независимо от того, откуда вызывается отчет, обработку можно разместить в модуле объекта отчета.
Рассмотрим процедуру ПриКомпоновкеРезультата в модуле отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, СхемаКомпоновкиДанных, ДанныеРасшифровки, СтандартнаяОбработка)
// Получаем текущую организацию пользователя
ОрганизацияПользователя = ОбщегоНазначения.ПолучитьОрганизациюПоУмолчанию();
Если ЗначениеЗаполнено(ОрганизацияПользователя) Тогда
// Добавляем или обновляем отбор в настройках компоновщика
НовыйЭлементОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйЭлементОтбора.ПравоеЗначение = ОрганизацияПользователя;
НовыйЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Если отбор должен быть виден пользователю в интерфейсе, но при этом заблокирован для изменения, необходимо скорректировать коллекцию пользовательских настроек после их загрузки платформой.
Выясним причину частой проблемы: если изменять доступность элементов отбора в событии ПриСозданииНаСервере, платформа может перезаписать эти изменения при автоматической загрузке сохраненных настроек пользователя. Чтобы этого избежать, используем событие ПриЗагрузкеПользовательскихНастроекНаСервере.
Посмотрим на пример кода в модуле формы:
&НаСервере
Процедура ПриЗагрузкеПользовательскихНастроекНаСервере(Настройки)
ОрганизацияПользователя = ОбщегоНазначения.ПолучитьОрганизациюПоУмолчанию();
// Обходим пользовательские настройки и блокируем поле
Для Каждого Элемент Из Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация") Тогда
Элемент.ПравоеЗначение = ОрганизацияПользователя;
Элемент.Использование = Истина;
Элемент.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важное примечание по безопасности: Программное скрытие или блокировка отборов в СКД решает интерфейсную задачу удобства работы. Если стоит критическая задача безопасности и разграничения доступа (чтобы пользователи гарантированно не могли получить доступ к чужим организациям ни через другие отчеты, ни через универсальные консоли), необходимо настраивать ограничение доступа на уровне записей (RLS) в правах ролей.