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