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