Как правильно получить физическое лицо текущего пользователя в 1С:Предприятие

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

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

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

Разбор архитектуры: Пользователь ИБ против справочника «Пользователи»

Перед тем как перейти к написанию кода, давайте разберем ключевую архитектурную особенность платформы 1С. Это поможет избежать самой распространенной ошибки, которую совершают начинающие разработчики.

В системе 1С существует жесткое разделение между двумя сущностями:

  1. Пользователь информационной базы (системный объект): Ссылка на него получается через менеджер ПользователиИнформационнойБазы. Этот объект отвечает исключительно за авторизацию, аутентификацию, системные роли и интерфейсные настройки. У него нет и не может быть прикладных реквизитов вроде «Физическое лицо», «Подразделение» или «Организация».
  2. Элемент справочника «Пользователи» (прикладной объект): Это обычный элемент базы данных. Именно в этом справочнике хранится вся прикладная информация о сотруднике, включая ссылку на справочник ФизическиеЛица.

Попытка обратиться напрямую к системному объекту платформы для получения физического лица вызовет ошибку компиляции или исключение во время выполнения приложения:


// ВНИМАНИЕ: Данный код ошибочен и приведет к падению системы!
ТекущийСистемныйПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
ФизЛицо = ТекущийСистемныйПользователь.ФизическоеЛицо; // Вызовет исключение!

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

Вариант 1. Прямое обращение (для самописных и устаревших конфигураций)

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

Если в системе настроена инициализация параметров сеанса при запуске, мы можем получить ссылку на текущего пользователя из параметров сеанса, а затем обратиться к его реквизиту:


// Получение физического лица через параметр сеанса (быстрый способ для простых конфигураций)
ТекущийПользовательСсылка = ПараметрыСеанса.ТекущийПользователь;
Если ЗначениеЗаполнено(ТекущийПользовательСсылка) Тогда
    ФизЛицо = ТекущийПользовательСсылка.ФизЛицо; // Имя реквизита зависит от вашей метаструктуры
КонецЕсли;

Этот способ прост и понятен, однако он имеет существенный недостаток, связанный с производительностью СУБД. Проанализируем, почему прямое обращение «через точку» к ссылке может замедлить работу системы.

Вариант 2. Оптимальное получение реквизита на сервере БСП

В современных конфигурациях, созданных на базе БСП (к ним относятся ERP, Комплексная автоматизация, Управление торговлей 11, Бухгалтерия предприятия 3.0, ЗУП 3.x), для получения текущего пользователя используется специализированный общий модуль Пользователи.

Если мы напишем код следующим образом:


// Рабочий, но неоптимальный код для БСП
ТекущийПользователь = Пользователи.ТекущийПользователь();
ФизЛицо = ТекущийПользователь.ФизическоеЛицо;

Платформа выполнит неявное считывание из базы данных всего объекта справочника Пользователи. Будут прочитаны все текстовые реквизиты, табличные части, настройки и двоичные данные, которые могут храниться в элементе. Для СУБД это оборачивается тяжелым SQL-запросом типа SELECT * FROM ....

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


// Оптимизированный и безопасный метод чтения реквизита на сервере БСП
ТекущийПользователь = Пользователи.ТекущийПользователь();
ФизЛицо = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ТекущийПользователь, "ФизическоеЛицо");

Функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта выполняет легкий точечный SQL-запрос, который извлекает исключительно значение поля ФизическоеЛицо, сводя на нет накладные расходы на чтение тяжелого объекта. Для быстрого поиска готовых конструкций и изучения типовых функций общих модулей подойдёт справочник по методам БСП с примерами вызовов.

Вариант 3. Особенности работы на клиенте (в управляемых формах)

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

Для решения этой проблемы в БСП предусмотрены специальные клиентские аналоги. Разберем по шагам, как получить данные пользователя на клиенте:

  1. Использовать метод ПользователиКлиент.ТекущийПользователь() для получения ссылки на пользователя.
  2. Если необходимо получить именно физическое лицо, следует организовать кратковременный внеконтекстный вызов сервера. Это минимизирует объем передаваемых данных между клиентом и сервером.

Посмотрим на практический пример реализации такого механизма:


&НаКлиенте
Процедура ПолучитьФизЛицоПриНеобходимости()
    
    // Получаем ссылку на пользователя на стороне клиента
    СсылкаНаПользователя = ПользователиКлиент.ТекущийПользователь();
    
    // Передаем ссылку на сервер без передачи контекста всей формы
    ТекущееФизЛицо = ПолучитьФизическоеЛицоНаСервере(СсылкаНаПользователя);
    
    Если ЗначениеЗаполнено(ТекущееФизЛицо) Тогда
        ПоказатьПредупреждение(, "Физическое лицо текущего пользователя: " + Строка(ТекущееФизЛицо));
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьФизическоеЛицоНаСервере(Знач ПользовательСсылка)
    
    // Используем самый быстрый способ получения значения реквизита
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПользовательСсылка, "ФизическоеЛицо");
    
КонецФункции

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

Вариант 4. Обработка сценариев с Внешними пользователями

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

Для предотвращения подобных сбоев мы должны использовать более гибкий метод БСП — АвторизованныйПользователь(). Этот метод автоматически определяет тип текущей сессии (внутренний сотрудник или внешний контрагент) и возвращает корректную ссылку.

Разберем универсальный алгоритм получения объекта авторизации (физического лица или партнера) для любых типов пользователей:


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

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

Резюме и рекомендации

Давайте подведем итог и составим краткий чек-лист по правильной работе с текущим пользователем и его физическим лицом в среде 1С:

← На главную