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