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