Как получить текущего пользователя и связанного сотрудника в 1С (БСП)?

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

При разработке расширений или доработке типовых конфигураций (таких как 1С:Управление торговлей 11, ERP, Комплексная автоматизация) часто возникает задача автоматического заполнения полей "Автор", "Ответственный" или "Менеджер" — для этого есть готовое расширение для заполнения реквизитов 1С. Поскольку современные конфигурации строятся на базе Библиотеки Стандартных Подсистем (БСП), использование старых методов или прямых обращений к параметрам сеанса не всегда является лучшей практикой. Рассмотрим правильные способы получения текущего пользователя и связанного с ним сотрудника.

Основные методы получения пользователя в БСП

В типовых конфигурациях существует различие между Пользователем Информационной Базы (учетная запись для входа в Конфигуратор/Предприятие) и элементом справочника Пользователи (сущность, используемая в документах и отчетах). Нам практически всегда нужна ссылка на элемент справочника.

Разберем методы, предоставляемые общими модулями БСП, в зависимости от контекста выполнения кода.

  1. На Сервере

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

    
    // Возвращает ссылку на справочник "Пользователи" или "ВнешниеПользователи"
    ТекущийПользовательСсылка = Пользователи.ТекущийПользователь();
    
  2. На Клиенте

    Если вам необходимо получить пользователя непосредственно в форме (например, при открытии) для проверки прав доступа, используйте клиентский общий модуль:

    
    // Работает на клиенте
    ТекущийПользовательСсылка = ПользователиКлиент.ТекущийПользователь();
    
  3. Универсальный вызов (Клиент и Сервер)

    В некоторых версиях БСП существует универсальный метод в модуле ПользователиКлиентСервер, однако в последних редакциях рекомендуется использовать разделение на Клиент/Сервер, описанное выше. Тем не менее, вы можете встретить или использовать:

    
    ПользователиКлиентСервер.ТекущийПользователь();
    

Где хранятся данные о пользователе?

Важно понимать механику работы. Данные о текущем пользователе хранятся в Параметрах Сеанса. Это специальные переменные, которые живут, пока активен сеанс пользователя.

Основной параметр: ПараметрыСеанса.ТекущийПользователь.

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

Важное замечание: Не путайте Пользователи.ТекущийПользователь() и ПользователиИнформационнойБазы.ТекущийПользователь(). Второй метод обращается к ядру платформы и возвращает объект администрирования (логин, пароль, роли), который нельзя записать в реквизит документа.

Задача: Получить сотрудника по текущему пользователю

Часто в документы (например, в "Реализацию товаров и услуг" или "Заказ клиента") нужно подставить не просто пользователя (системную учетку), а конкретного Сотрудника (Менеджера, Кладовщика) (поможет автоматическая подстановка подписей и факсимиле сотрудников). Пользователь и Сотрудник — это разные справочники.

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

Способ 1: Поиск через регистр соответствия (Рекомендуемый для УТ/ERP)

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

Рассмотрим пример функции для получения сотрудника:


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

Способ 2: Поиск через Физлицо (Архитектурно правильный)

В более сложных системах (ЗУП, комплексные ERP) связь строится через справочник ФизическиеЛица. Цепочка выглядит так: Пользователь -> Физическое Лицо -> Сотрудник.

Это связано с тем, что один человек (Физлицо) может работать по совместительству на двух должностях (два элемента справочника Сотрудники), но под одной учетной записью (один Пользователь).

Способ 3: Поиск по наименованию (Не рекомендуется)

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


// Плохой пример, старайтесь избегать такого подхода
Сотрудник = Справочники.Сотрудники.НайтиПоНаименованию(Пользователи.ТекущийПользователь().Наименование);

Нюансы работы с выборкой запроса

Обратите внимание на конструкцию, использованную в примере выше:


Сотрудник = ?(Выборка.Следующий(), Выборка.Сотрудник, Справочники.Сотрудники.ПустаяСсылка());

Метод Выборка.Следующий() возвращает тип Булево. Если данных в выборке нет (запрос ничего не нашел), метод вернет Ложь и не вызовет исключения (ошибки). Поэтому проверка Результат.Пустой() перед вызовом Следующий() технически не обязательна, если вы корректно обрабатываете результат Ложь.

Как реализовать автозаполнение в форме документа

Если вы хотите, чтобы при создании документа или изменении ключевых полей (например, Партнера) менялся Ответственный или Менеджер, код следует размещать в обработчиках событий формы или объекта — для этого подойдёт универсальная настройка автозаполнения документов.

Рассмотрим алгоритм действий в расширении для формы документа:

  1. Создайте расширение и заимствуйте форму документа.
  2. В обработчик ПриСозданииНаСервере добавьте код для начального заполнения (если это новый документ).
  3. В обработчик ПриИзменении поля "Клиент" (или другого влияющего реквизита) добавьте вызов функции пересчета менеджера.

Пример кода для формы:


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

Используя эти методы, вы гарантируете совместимость вашего кода с механизмами БСП и корректную работу в клиент-серверной архитектуре.

← На главную