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