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