Как программно выбрать пользователя из справочника «Пользователи» в 1С?

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

В разработке на платформе 1С:Предприятие часто возникает задача программного заполнения реквизитов. Одной из самых распространенных операций является поиск конкретного пользователя в справочнике Пользователи и подстановка его в поле документа или формы. Несмотря на кажущуюся простоту, новички часто сталкиваются с тем, что код не выдает ошибок, но поле реквизита остается пустым. Разберем подробно, почему это происходит и как правильно решить эту задачу разными способами.

Анализируем проблему метода НайтиПоНаименованию

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

Реквизит1 = Справочники.Пользователи.НайтиПоНаименованию("Иванов");

Почему этот код может не работать? Проанализируем основные причины:

  1. Неточное соответствие: Метод НайтиПоНаименованию по умолчанию ищет точное совпадение. Если в справочнике пользователь записан как «Иванов Иван Иванович» или просто имеет лишний пробел в конце («Иванов »), система не найдет его по строке «Иванов» и вернет Справочники.Пользователи.ПустаяСсылка().
  2. Поиск по вхождению: У данного метода есть второй параметр. Если мы напишем НайтиПоНаименованию("Иванов", Ложь), поиск будет идти строго с начала строки. Если установить Истина, поиск станет более гибким, но возникнет риск найти не того пользователя, если в базе несколько людей с похожими фамилиями.
  3. Контекст выполнения: В управляемом приложении (платформа 8.3) обращение к менеджеру Справочники напрямую на стороне клиента (в процедурах &НаКлиенте) невозможно. Подобный код должен выполняться только на сервере.

Разберем правильную структуру вызова (Клиент-Сервер)

Если ваша задача — заполнить реквизит по нажатию кнопки на форме, необходимо правильно распределить код между клиентом и сервером. Выясним, как это реализовать. На клиенте мы вызываем команду, а поиск выполняем на сервере, чтобы иметь доступ к базе данных.

Пример реализации в модуле формы:


&НаКлиенте
Процедура ЗаполнитьПользователя(Команда)
    // Вызываем серверную функцию для поиска
    НайденныйПользователь = НайтиПользователяНаСервере("Иванов");
    
    Если НЕ НайденныйПользователь.Пустая() Тогда
        Объект.Реквизит1 = НайденныйПользователь;
    Иначе
        Сообщить("Пользователь не найден!");
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция НайтиПользователяНаСервере(ИмяПользователя)
    // На сервере нам доступен глобальный менеджер справочников
    Возврат Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя);
КонецФункции

Важный момент: Использование директивы &НаСервереБезКонтекста повышает производительность, так как на сервер не передаются все данные формы.

Использование запроса — профессиональный подход

Опытные разработчики редко используют НайтиПоНаименованию для критически важных участков кода. Запрос работает быстрее, надежнее и позволяет точно контролировать результат. Посмотрим на пример поиска через запрос, который исключает ошибки типизации и позволяет найти пользователя, даже если его наименование содержит лишние символы.


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

В данном примере мы использовали оператор ПОДОБНО, что позволяет найти пользователя, даже если в базе указано его полное имя, а мы ищем только по фамилии. Также мы добавили проверку на ПометкаУдаления, чтобы не выбирать неактивных сотрудников.

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

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

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


// В современных конфигурациях (УТ 11, БП 3.0, ЗУП 3.1)
Объект.Реквизит1 = Пользователи.АвторизованныйПользователь();

Если БСП не используется, можно найти ссылку по имени системного пользователя:


ИмяИБ = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя;
СсылкаНаПользователя = Справочники.Пользователи.НайтиПоНаименованию(ИмяИБ);

Рекомендации по «хардоку» и предопределенным данным

Прописывание имен пользователей строками прямо в коде (например, "Иванов") считается плохой практикой (так называемый «хардкод»). Если завтра пользователя «Иванов» переименуют в интерфейсе или он сменит фамилию, ваш код перестанет работать.

Рассмотрим более правильные альтернативы:

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

← На главную