Как определить текущего пользователя при начале работы системы в управляемом приложении 1С

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

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

Разберем причину возникновения проблемы

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

  1. Менеджер ПользователиИнформационнойБазы доступен только на сервере, в толстом клиенте или во внешнем соединении. Попытка вызвать его на тонком клиенте приведет к ошибке компиляции.
  2. Параметры сеанса физически хранятся на сервере. Хотя они доступны для чтения на клиенте, их необходимо предварительно инициализировать в специальном серверном событии, иначе при обращении к ним клиент получит исключение или пустое значение.

Шаг 1: Инициализация через модуль сеанса

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

Выясним, как должен выглядеть код в модуле сеанса для нетиповой конфигурации:


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

КонецПроцедуры

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

Шаг 2: Использование возможностей БСП

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

Для получения текущего авторизованного пользователя в коде (как на клиенте, так и на сервере) рекомендуется использовать функцию:

Пользователи.АвторизованныйПользователь()

Проанализируем, почему это лучше:

При объединении вашей конфигурации с БСП крайне важно не забыть скопировать содержимое Модуля сеанса и Модуля управляемого приложения из шаблона БСП, так как именно там прописаны вызовы процедур инициализации системных параметров.

Шаг 3: Оптимизация доступа через кэширование на сервере

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


// Общий модуль: РаботаСПользователямиСервер (Флаги: Сервер, Вызов сервера, Повт. исп. на время сеанса)

Функция ПолучитьТекущегоПользователя() Экспорт
    
    // Возвращаем параметр сеанса. Благодаря кэшированию 1С, 
    // этот код выполнится реально только один раз за сеанс.
    Возврат ПараметрыСеанса.ТекущийПользователь;
    
КонецФункции

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

Подведем итоги и проанализируем ситуацию

Мы выяснили, что попытка напрямую определить пользователя в ПриНачалеРаботыСистемы() через серверные методы обречена на провал из-за контекстных ограничений. Чтобы решить задачу, выполните следующие действия:

  1. Убедитесь, что в Модуле сеанса прописана инициализация параметра сеанса ТекущийПользователь.
  2. Если используется БСП, проверьте наличие справочника Пользователи и корректность переноса кода в системные модули.
  3. Используйте общие модули с повторным использованием значений для обеспечения быстрого доступа к данным пользователя.
  4. Различайте системную учетную запись (строковое имя или UUID) и прикладной объект в базе данных (ссылка справочника).

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

← На главную