Как получить список пользователей с определенной ролью с помощью запроса в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке на платформе 1С:Предприятие программисты часто сталкиваются с задачей: выбрать всех пользователей, которым назначена конкретная роль (например, «МенеджерПоПродажам» или «ПолныеПрава»), чтобы затем использовать этот список в отчете, обработке или механизме ограничения доступа RLS (Record Level Security). Однако попытка сделать это «в лоб» через стандартный конструктор запроса заканчивается неудачей, так как таблицы ролей не являются обычными объектами метаданных.

В этой статье мы подробно разберем, почему запрос не видит роли напрямую, и рассмотрим несколько эффективных способов решения этой задачи для конфигураций на обычных формах, таких как УТ 2.3.

Почему нельзя просто «потянуть» роль в запросе?

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В 1С данные делятся на две принципиально разные категории:

  1. Данные информационной базы: это справочники, документы, регистры. К ним язык запросов 1С имеет прямой доступ.
  2. Объекты конфигурации и системные данные: роли, пользователи информационной базы (ИБ), права доступа.

Роли хранятся в системных таблицах, которые недоступны стандартному объекту Запрос. Поэтому написать что-то вроде ВЫБРАТЬ Пользователи.Ссылка ГДЕ Пользователи.Роль = &ИмяРоли невозможно. Чтобы решить задачу, нам придется использовать «обходные пути». Для интерактивного сопоставления и анализа прав и ролей пользователей можно использовать обработку для просмотра прав и анализа ролей.

Способ 1: Программный перебор пользователей через объект ПользователиИнформационнойБазы

Наиболее распространенный и надежный метод — это программное получение списка имен или идентификаторов пользователей и последующая передача этого списка в запрос в качестве параметра. Рассмотрим подробнее, как реализовать этот алгоритм.

Сначала нам нужно создать массив или список значений, в который мы поместим всех подходящих пользователей. Разберем по шагам пример кода:


// Создаем список для хранения ссылок на пользователей
СписокНужныхПользователей = Новый СписокЗначений;

// Получаем массив всех пользователей, зарегистрированных в ИБ
ВсеПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();

// Указываем имя роли, которую ищем
ИскомаяРоль = "АБВ"; // Замените на имя вашей роли из конфигуратора

Для Каждого ПользовательИБ Из ВсеПользователиИБ Цикл
    // Проверяем наличие роли у конкретного пользователя
    Если ПользовательИБ.Роли.Содержит(Метаданные.Роли[ИскомаяРоль]) Тогда
        // Находим соответствующую ссылку в справочнике "Пользователи"
        // Обычно поиск идет по имени или по Уникальному Идентификатору
        СсылкаНаПользователя = Справочники.Пользователи.НайтиПоНаименованию(ПользовательИБ.Имя);
        
        Если Не СсылкаНаПользователя.Пустая() Тогда
            СписокНужныхПользователей.Добавить(СсылкаНаПользователя);
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

После того как список сформирован, мы можем легко использовать его в запросе. Посмотрим на пример:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Продажи.СуммаОборота,
    |   Продажи.Менеджер
    |ИЗ
    |   РегистрНакопления.Продажи.Обороты КАК Продажи
    |ГДЕ
    |   Продажи.Менеджер В (&СписокПользователей)";

Запрос.УстановитьПараметр("СписокПользователей", СписокНужныхПользователей);
Результат = Запрос.Выполнить();

Способ 2: Использование параметров сеанса и RLS

Если ваша задача связана с ограничением прав доступа (RLS), чтобы, например, менеджер видел документы только своих подчиненных (продавцов), то прямой перебор в модуле документа будет работать медленно. В этом случае выясним причину использования параметров сеанса.

Параметры сеанса инициализируются один раз при запуске программы. Вы можете создать параметр сеанса ТекущиеПродавцыДляМенеджера с типом ФиксированныйМассив. При запуске системы код проверяет роль текущего пользователя, и если он является менеджером, программно заполняет этот массив списком продавцов.

В тексте ограничения RLS запрос будет выглядеть так:

ГДЕ Ответственный В (&ТекущиеПродавцыДляМенеджера)

Важный нюанс: Внутри самого запроса RLS доступна функция РольДоступна("ИмяРоли"). Однако она проверяет права только текущего пользователя. Вы не можете использовать её для проверки прав другого пользователя внутри одной выборки. Для детального анализа связей ролей, групп доступа и условий RLS подойдёт инструмент для работы с правами и ограничениями RLS.

Способ 3: Создание вспомогательного регистра (Архитектурный подход)

Для высоконагруженных систем или сложных отчетов постоянный перебор всех пользователей информационной базы (которых может быть несколько сотен) является неэффективным. Рассмотрим более профессиональный метод — дублирование информации в данные.

Проанализируем шаги реализации:

  1. Создаем новый Регистр сведений (например, СоставРолейПользователей) с измерениями Пользователь и Роль.
  2. В модуле сеанса или в процедуре при записи пользователя ИБ прописываем обновление этого регистра.
  3. Теперь роли стали обычными данными! Вы можете соединять этот регистр в любом запросе обычным ЛЕВОЕ СОЕДИНЕНИЕ.

Этот подход реализован во всех современных конфигурациях на базе БСП (Библиотека стандартных подсистем), но в старой УТ 2.3 его придется добавить вручную. Это позволит вам выполнять задачи любой сложности мгновенно, не нагружая систему постоянным опросом списка пользователей ИБ.

Способ 4: Прямые SQL-запросы (Для опытных администраторов)

Если база данных находится на клиент-серверном варианте (MS SQL или PostgreSQL), существует теоретическая возможность выполнить прямой запрос к таблице v8users. Однако делать это крайне не рекомендуется по следующим причинам:

Итоги и рекомендации

Мы рассмотрели различные варианты решения задачи. Подведем итог:

Если вам нужно разово получить список для отчета, используйте Способ 1 (программный перебор ПользователиИнформационнойБазы). Если же вы строите сложную систему разграничения прав или часто формируемый отчет, лучше один раз потратить время на создание регистра сведений (Способ 3), чтобы в дальнейшем иметь возможность «тянуть» роли обычным, быстрым запросом.

Помните, что при проверке ролей всегда стоит учитывать наличие у пользователя роли ПолныеПрава. В большинстве бизнес-логик «Администратор» должен попадать в любой список, даже если специфическая роль «АБВ» ему явно не назначена. Для этого в коде проверки добавляйте условие:


Если ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава) 
   ИЛИ ПользовательИБ.Роли.Содержит(Метаданные.Роли[ИскомаяРоль]) Тогда
   // Добавляем в список...
КонецЕсли;
← На главную