Как отобразить объекты в отборах СКД, если у пользователя нет прав доступа на их чтение?

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

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

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

Почему стандартный привилегированный режим не помогает в отборах?

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

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

Решение 1. Использование программного заполнения «Доступных значений»

Это один из самых изящных способов. В схеме компоновки данных у каждого поля есть свойство ДоступныеЗначения. Если этот список заполнен, 1С вместо открытия полноценной формы списка (где действуют ограничения прав) покажет пользователю простой выпадающий список или мини-форму с заранее подготовленными элементами.

Рассмотрим алгоритм действий:

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

Посмотрим на пример кода:


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

Поскольку запрос в функции ПолучитьПолныйСписокСкладовПривилегированно будет выполняться в привилегированном модуле, он проигнорирует RLS и вернет все записи, которые затем станут доступны пользователю для выбора в отчете.

Решение 2. Использование параметров вместо стандартных отборов

Если штатные отборы на вкладке «Отбор» слишком жестко следуют правам доступа, мы можем использовать Параметры данных. Для параметров в СКД можно настроить список выбора более гибко.

Разберем ситуацию по шагам:

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

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


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

Решение 3. Кастомная форма выбора (Метод "Костыля" через строковое представление)

Если нам нужно сохранить стандартный интерфейс отборов, но разрешить выбор "запрещенных" объектов, можно пойти по пути создания собственной формы выбора.

Рассмотрим подробнее этот сценарий:

  1. Добавим на форму отчета строковый реквизит, который будет служить для отображения (например, СкладПредставление).
  2. При нажатии на кнопку выбора этого реквизита открываем свою форму списка, которую заполняем вручную (например, через таблицу значений), выполнив запрос в привилегированном режиме.
  3. Пользователь выбирает объект из этого списка.
  4. Программно передаем выбранную ссылку в настройки компоновщика отчета.

Выясним, как это выглядит в коде при установке отбора:


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

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

Важный нюанс: чтобы пользователь увидел результат отчета по этому складу, процедура ПриКомпоновкеРезультата также обязательно должна содержать УстановитьПривилегированныйРежим(Истина), иначе запрос компоновки отсечет данные по RLS уже при выполнении.

Решение 4. Настройка минимальных прав через дополнительную роль

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

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

Для решения задачи:

Дополнительные технические нюансы

Проанализируем еще два важных момента, которые могут блокировать отображение объектов:

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

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

Подведем итог: для решения проблемы выбора "невидимых" объектов в СКД лучше всего использовать программное заполнение ДоступныеЗначения или механизм Параметров данных с предварительной подготовкой списка в привилегированном модуле на сервере. Это сохранит чистоту интерфейса и обеспечит корректную работу отчета под любыми правами доступа.

← На главную