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