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