Как определить текущего пользователя в 1С 8.3 программно

· 9 мин

Содержание

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

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

Глобальные функции: имя пользователя сеанса без лишних объектов

Самый короткий путь — функции глобального контекста. Они доступны и на клиенте, и на сервере, не требуют прав администратора и работают в любой конфигурации, даже в пустой.

Функция (рус.)Функция (англ.)Что возвращает
ИмяПользователя()UserName()Имя для входа, строка
ПолноеИмяПользователя()UserFullName()Полное имя из списка пользователей, строка
РольДоступна(Роль)IsInRole(Role)Истина, если у пользователя есть роль
НомерСеансаИнформационнойБазы()InfoBaseSessionNumber()Номер текущего сеанса, число

Пример — вывести, кто сейчас работает:

&НаКлиенте
Процедура ПоказатьПользователя(Команда)
    Сообщить("Вы вошли как: " + ИмяПользователя()
        + " (" + ПолноеИмяПользователя() + ")");
КонецПроцедуры

Проверка роли принимает либо объект метаданных, либо имя роли строкой:

Если РольДоступна("ПолныеПрава") Тогда
    // разрешаем служебную команду
КонецЕсли;

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

Ограничение у глобальных функций одно: они возвращают строки. Имя пользователя администратор может поменять в любой момент, поэтому хранить его в данных как ключ — плохая идея. Для связи с данными нужен идентификатор или ссылка.

Чем ИмяПользователя() отличается от объекта ПользовательИнформационнойБазы

Новички часто путают два уровня. Первый — пользователь информационной базы: учётная запись платформы, которую видно в Конфигураторе через Администрирование → Пользователи. Второй — элемент справочника «Пользователи» в конфигурации, если он там есть.

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

КритерийИмяПользователя()ПользователиИнформационнойБазы.ТекущийПользователь()
Тип результатаСтрокаПользовательИнформационнойБазы
Где вызываетсяКлиент и серверСервер, толстый клиент, внешнее соединение
Даёт идентификаторНетДа, УникальныйИдентификатор
Даёт ролиНет (только проверка через РольДоступна)Да, коллекция Роли
Устойчив к переименованиюНетИдентификатор — да

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

&НаСервереБезКонтекста
Функция ИдентификаторТекущегоПользователя()
    Возврат ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
КонецФункции

Отдельная история — внешние пользователи в конфигурациях на БСП (контрагенты, партнёры, работающие через веб-кабинет). Для платформы это такие же пользователи информационной базы, а в данных они связаны со справочником «Внешние пользователи». Поэтому в БСП есть две функции: ТекущийПользователь() вернёт ссылку только для обычного пользователя, а АвторизованныйПользователь() — для любого из двух видов.

Получаем объект ПользовательИнформационнойБазы и ссылку на справочник

Свойства объекта пользователя

После вызова ПользователиИнформационнойБазы.ТекущийПользователь() на сервере доступны основные свойства:

  • 🔑 Имя — имя для входа;
  • 👤 ПолноеИмя — как пользователь назван в списке;
  • 🆔 УникальныйИдентификатор — постоянный ключ учётной записи;
  • 🛡️ Роли — коллекция ролей, можно перебрать или проверить через Содержит();
  • 🖥️ АутентификацияОС и ПользовательОС — вход через Windows и привязанная учётная запись домена;
  • 🔐 АутентификацияСтандартная — вход по логину и паролю 1С.

Пример: собрать строку с ролями текущего пользователя для отладочного сообщения.

&НаСервере
Функция СписокРолейТекущегоПользователя()
    ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
    Имена = Новый Массив;
    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        Имена.Добавить(Роль.Имя);
    КонецЦикла;
    Возврат СтрСоединить(Имена, ", ");
КонецФункции

Получить себя может любой пользователь. А вот искать других — НайтиПоИмени(), НайтиПоУникальномуИдентификатору(), ПолучитьПользователей() — можно только с правом администрирования. Обычный пользователь получит исключение. Если такой поиск нужен в рабочем коде, оборачивайте его в серверную функцию с УстановитьПривилегированныйРежим(Истина).

Ссылка на элемент справочника «Пользователи»

В конфигурациях на БСП элемент справочника хранит идентификатор пользователя ИБ в реквизите ИдентификаторПользователяИБ. Вручную искать по нему не нужно — библиотека уже делает это при старте сеанса и кладёт результат в параметр сеанса.

Где выполняется кодЧто вызвать
СерверПользователи.ТекущийПользователь()
Сервер, с учётом внешних пользователейПользователи.АвторизованныйПользователь()
КлиентПользователиКлиент.ТекущийПользователь()
Клиент, с учётом внешних пользователейПользователиКлиент.АвторизованныйПользователь()
Сервер, напрямуюПараметрыСеанса.ТекущийПользователь

Типичный сценарий — заполнить ответственного при создании документа:

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

Если конфигурация самописная и справочника «Пользователи» нет, свяжите данные с учётной записью через УникальныйИдентификатор. Строковое имя для этого не годится: после переименования связь потеряется.

Что вам нужно получить о текущем пользователе?

Сведения о сеансе: компьютер, приложение, время входа

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

  • 💻 ИмяКомпьютера — с какой машины подключились;
  • 📱 ИмяПриложения — тонкий клиент, веб-клиент, фоновое задание, COM-соединение и т. д.;
  • 🕐 НачалоСеанса — дата и время входа;
  • 🔢 НомерСеанса — тот же номер, что показывает консоль кластера.
&НаСервереБезКонтекста
Функция ОписаниеСеанса()
    Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
    Возврат Сеанс.Пользователь.Имя + " с компьютера " + Сеанс.ИмяКомпьютера
        + ", вход " + Формат(Сеанс.НачалоСеанса, "ДФ='dd.MM.yyyy HH:mm'");
КонецФункции

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

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

Кто «текущий пользователь» в распределённой базе и при обмене

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

Что из этого следует на практике:

  1. Связывайте документы со ссылкой на элемент справочника «Пользователи», а не с именем и не с идентификатором ИБ. Справочник — обычные данные, они уходят в обмен вместе с документами.
  2. Определяйте, в каком узле выполняется код, через ПланыОбмена.ГлавныйУзел(). В главном узле функция возвращает Неопределено, в подчинённом — ссылку на главный узел.
  3. При загрузке данных обменом не перезаписывайте автора текущим пользователем.

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

Процедура ПередЗаписью(Отказ)
    Если ОбменДанными.Загрузка Тогда
        Возврат; // данные пришли обменом — автора не трогаем
    КонецЕсли;
    Если Не ЗначениеЗаполнено(Автор) Тогда
        Автор = Пользователи.ТекущийПользователь();
    КонецЕсли;
КонецПроцедуры

То же правило касается обменов с другими базами через универсальный формат: проверка ОбменДанными.Загрузка должна стоять первой строкой обработчика.

Параметры сеанса, константы и настройки пользователя

Параметр сеанса — быстрый доступ без запросов

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

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

Здесь Сотрудники и ИдентификаторПользователя — имена из вашей конфигурации; замените их на свои. Параметр читается один раз за сеанс, дальше обращение к нему ничего не стоит.

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

В обычном запросе параметр сеанса сам не подставляется. Передайте его явно: Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь).

Константы и хранилища настроек

Константы общие для всей базы, персональные данные в них не хранят. Зато через константу удобно задать служебную учётную запись — например, «Пользователь для регламентных заданий» — и сравнивать с ней ИмяПользователя(), чтобы фоновый код вёл себя иначе, чем интерактивный.

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

ХранилищеОбщихНастроек.Сохранить("МояОбработка", "ПоследнийСклад", Склад);
Склад = ХранилищеОбщихНастроек.Загрузить("МояОбработка", "ПоследнийСклад");

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

Пустой пользователь, фоновые задания и ошибки

База без списка пользователей

Если в Конфигураторе список пользователей пуст, 1С пускает в базу без авторизации. В этом случае:

  • ИмяПользователя() возвращает пустую строку;
  • у объекта ТекущийПользователь() пустые Имя и ПолноеИмя, а идентификатор состоит из нулей;
  • в БСП текущим становится служебный элемент справочника с наименованием вроде «<Не указан>».

Проверка на этот случай простая:

Если ПустаяСтрока(ИмяПользователя()) Тогда
    // пользователи не заведены — права не проверяем, автора не пишем
КонецЕсли;

Не стройте защиту данных на проверке имени пользователя. В базе без списка пользователей у входящего полные права, и код, который «пропускает только Иванова», ничего не защищает.

Фоновые и регламентные задания

Фоновое задание, запущенное из кода, выполняется от имени того, кто его запустил. У регламентного задания пользователь задаётся в его свойствах. Если там пусто, ИмяПользователя() внутри задания может вернуть пустую строку — и код, рассчитанный на заполненное имя, упадёт или запишет пустого автора. Задайте в свойствах задания конкретную служебную запись, а в коде проверяйте результат на пустоту.

Диагностика: выберите симптом

Частые вопросы

Как получить текущего пользователя в запросе?
Встроенной функции языка запросов для этого нет. Передайте значение параметром: Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь()).
Можно ли узнать пользователя Windows, под которым запущена 1С?
Если включена аутентификация операционной системы, привязанная доменная учётная запись хранится в свойстве ПользовательОС объекта пользователя ИБ. Без такой привязки свойство пустое.
Чем ИмяПользователя() отличается от ПолноеИмяПользователя()?
Первая функция возвращает логин для входа, вторая — отображаемое имя из списка пользователей, например «Иванова Мария Петровна».
Как проверить, что пользователь — администратор?
Проверьте роль: РольДоступна(Метаданные.Роли.ПолныеПрава). В конфигурациях на БСП есть готовая функция Пользователи.ЭтоПолноправныйПользователь().
Что вернёт ИмяПользователя() во внешнем соединении?
Имя учётной записи, указанной в строке подключения (параметр Usr). Поэтому для интеграций заводят отдельного пользователя с понятным именем.