Как найти пользователя в 1С по имени пользователя ОС (логину домена)

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает задача определить конкретного пользователя в справочнике Пользователи, имея на руках только строковое представление его логина в операционной системе (например, «domain\user»). Сложность заключается в том, что в типовой платформе 1С:Предприятие 8 данные об аутентификации ОС хранятся в объектах ПользовательИнформационнойБазы, которые не являются ссылочными данными и к которым нельзя обратиться через обычный запрос SELECT.

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

Различие между Пользователями ИБ и справочником «Пользователи»

Для начала разберем важный архитектурный нюанс. В 1С существует два уровня сущностей:

  1. Пользователи информационной базы (Пользователи ИБ): это системные объекты платформы. Они отвечают за авторизацию, хранят пароли, роли и настройки аутентификации ОС. К ним нельзя обратиться через запрос ВЫБРАТЬ.
  2. Справочник Пользователи: это прикладной объект (обычно часть БСП). Он используется в документах и отчетах. В нем есть реквизит ИдентификаторПользователяИБ (тип УникальныйИдентификатор), который служит ключом для связи со вторым уровнем.

Наша задача — найти Пользователя ИБ, у которого свойство ПользовательОС совпадает с искомой строкой, получить его УникальныйИдентификатор и по нему найти ссылку в справочнике.

Решение проблемы через перебор списка пользователей

Поскольку платформа не предоставляет метода НайтиПоРеквизиту для списка пользователей информационной базы (кроме поиска по имени и полному идентификатору), нам придется использовать метод ПолучитьПользователей(). Проанализируем пример кода, который решает эту задачу:


// Искомая строка (Curator), например: "Windows:DOMAIN\UserName"
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
СсылкаНаПользователя = Справочники.Пользователи.ПустаяСсылка();

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

Если НЕ СсылкаНаПользователя.Пустая() Тогда
    // Дальнейшая логика работы с найденным пользователем
КонецЕсли;

В данном примере мы сначала выгружаем весь список пользователей системы в массив, а затем в цикле ищем совпадение по свойству ПользовательОС. Как только совпадение найдено, мы используем УникальныйИдентификатор системного пользователя для поиска элемента в справочнике Пользователи.

Важные нюансы формата строки «Пользователь ОС»

Проанализируем ситуацию, когда сравнение ПользовательИБ.ПользовательОС = Curator может не сработать. Платформа 1С хранит данные аутентификации в специфических форматах. Обычно это:

Если в вашей переменной Curator просто записано «domain\user», прямое равенство выдаст Ложь. Рекомендуется перед поиском приводить строку к нужному формату или использовать функцию СтрНайти, хотя это может быть чуть медленнее. Также учитывайте, что в некоторых конфигурациях (особенно на Linux-серверах) регистр символов может иметь значение.

Проблема производительности метода GetUsers()

Рассмотрим подробнее работу метода ПользователиИнформационнойБазы.ПолучитьПользователей(). Этот метод при каждом вызове обращается к системным таблицам и считывает данные всех пользователей. Если в вашей базе 10–20 пользователей, вы не заметите задержек. Однако в крупных корпоративных системах, где количество пользователей исчисляется сотнями или тысячами, этот вызов может занимать несколько секунд.

Критически важно: не вызывайте этот код внутри циклов обработки документов или при записи каждой строки большой таблицы. Если вам нужно найти 100 кураторов для 100 договоров, лучше один раз получить список пользователей ИБ, выгрузить его в ТаблицуЗначений или Соответствие, и далее искать уже в подготовленном кэше в памяти.

Оптимальный архитектурный подход

Если задача поиска пользователя по ОС возникает регулярно (например, при импорте данных или автоматическом распределении задач), правильнее будет изменить структуру данных. Разберем, как это сделать:

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

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |   Пользователи.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Пользователи КАК Пользователи
    |ГДЕ
    |   Пользователи.ИмяПользователяОС = &ИмяОС
    |   И НЕ Пользователи.ПометкаУдаления";

Запрос.УстановитьПараметр("ИмяОС", ИскомыйЛогин);
Результат = Запрос.Выполнить();

Использование функций БСП

Если ваша конфигурация построена на Библиотеке Стандартных Подсистем (БСП), выясним, как упростить задачу. В БСП существует общий модуль Пользователи. Хотя прямого поиска по ОС там может не быть, полезно использовать методы для получения идентификаторов:

Идентификатор = Пользователи.ИдентификаторПользователяИБ(НужныйПользователь);

Это гарантирует корректную работу с уникальными идентификаторами, которые могут отличаться в разных версиях платформы.

Резюме

Для разовой задачи или небольшой базы метод с перебором ПолучитьПользователей() вполне допустим и прост в реализации. Однако для высоконагруженных систем или частых операций поиска всегда стремитесь к кэшированию данных в справочнике или регистре сведений, чтобы использовать мощь SQL-запросов вместо линейного перебора в коде 1С.

← На главную