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