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