Как в отчете на СКД жестко зафиксировать отбор по организации без возможности изменения пользователем?

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

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

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

Способ 1. Использование механизма фиксированных настроек СКД

Наиболее корректным архитектурным подходом для управляемых форм является использование свойства ФиксированныеНастройки у объекта КомпоновщикНастроек. Фиксированные настройки применяются платформой поверх пользовательских настроек по логическому условию «И», при этом платформа автоматически исключает такие отборы из окна настроек и панели быстрых пользовательских отборов.

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

  1. Откроем форму отчета и найдем серверное событие ПриСозданииНаСервере.
  2. Получим организацию текущего пользователя из информационной базы.
  3. Добавим элемент отбора в коллекцию Отчет.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.

Посмотрим на пример реализации данного метода:


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

КонецПроцедуры

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

Способ 2. Использование параметров СКД с вычисляемым выражением

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

Проанализируем шаги настройки в схеме компоновки данных:

  1. Перейдем на вкладку Параметры в схеме компоновки данных.
  2. Найдем параметр Организация (или создадим его, если фильтрация выполняется в запросе через ГДЕ Организация = &Организация).
  3. Снимем флажок Включать в пользовательские настройки, чтобы параметр не отображался на форме отчета.
  4. Установим флажок Ограничение доступности.
  5. В колонке Выражение пропишем вызов экспортной функции общего модуля, возвращающей организацию текущего пользователя, например: ОбщегоНазначения.ПолучитьОрганизациюПоУмолчанию().

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

Способ 3. Переопределение отбора в модуле отчета при компоновке данных

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

Рассмотрим процедуру ПриКомпоновкеРезультата в модуле отчета:


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

КонецПроцедуры

Способ 4. Управление пользовательскими настройками формы

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

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

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


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

КонецПроцедуры

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

← На главную