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