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