Текущий пользователь в 1С 8.3: как получить его в коде, запросе и фоновом задании

· 9 мин

Содержание

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

Какой метод выбрать, зависит от того, что вам нужно: логин для проверки, ФИО для печатной формы или ссылка для отбора. Ниже — разница между ними, примеры кода для 1С:Предприятия 8.3 и ловушки фоновых заданий и веб-клиента.

Два «пользователя» в 1С и какой из них вам нужен

В базе на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11, ERP) у каждого сотрудника две записи:

  • 🔐 Пользователь информационной базы — объект платформы. Логин, пароль, роли, способ входа. Хранится вне справочников, в коде это тип ПользовательИнформационнойБазы.
  • 📇 Элемент справочника «Пользователи» — обычная ссылка. Её записывают в реквизиты «Ответственный», «Автор», используют в отборах и регистрах.

Связь между ними держится на реквизите ИдентификаторПользователяИБ справочника: там лежит уникальный идентификатор платформенного пользователя.

Что нужноЧто получатьМетод
Логин для проверки или логаСтрокаИмяПользователя()
ФИО для печатной формыСтрокаПолноеИмяПользователя()
Роли, способ входа, идентификаторПользовательИнформационнойБазыПользователиИнформационнойБазы.ТекущийПользователь()
Значение для реквизита или запросаСправочникСсылка.ПользователиПользователи.ТекущийПользователь()

Если конфигурация самописная и справочника пользователей в ней нет, вам доступен только платформенный уровень. Всё про БСП в этом случае пропускайте.

Метод ТекущийПользователь() на уровне платформы

Менеджер ПользователиИнформационнойБазы доступен на сервере, в толстом клиенте и во внешнем соединении. В тонком и веб-клиенте его нет, поэтому код размещают в серверной процедуре.

&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()

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

    Результат = Новый Структура;
    Результат.Вставить("Имя",           ПользовательИБ.Имя);
    Результат.Вставить("ПолноеИмя",     ПользовательИБ.ПолноеИмя);
    Результат.Вставить("Идентификатор", ПользовательИБ.УникальныйИдентификатор);

    Возврат Результат;

КонецФункции

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

  • 🎭 Роли — коллекция назначенных ролей, проверяется через Содержит();
  • 🔑 АутентификацияСтандартная, АутентификацияОС — какие способы входа включены;
  • 🌐 Язык — язык интерфейса пользователя;
  • 🆔 УникальныйИдентификатор — не меняется при переименовании логина, поэтому для связей и логов надёжнее имени.
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЕстьПолныеПрава = ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава);

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

Чтобы проверить одну роль, удобнее глобальная функция РольДоступна("ИмяРоли"). Она учитывает роли текущего сеанса, и ей не нужен объект пользователя.

Проверка прав вместо проверки ролей

Часто пользователя определяют только ради вопроса «можно ли ему это». Тогда надёжнее спрашивать не про роль, а про право на конкретный объект:

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

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

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

Логин и полное имя: ИмяПользователя() и ПолноеИмяПользователя()

Обе функции — глобальный контекст, работают и на сервере, и на клиенте, в том числе в веб-клиенте. Это самый короткий способ узнать, кто сейчас в программе.

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

Чем различаются два значения:

СвойствоПримерГде видноДля чего
Имя (логин)ivanovaОкно входаПроверки в коде, логи, обмены
Полное имяИванова Анна СергеевнаЗаголовок окна, спискиПечатные формы, сообщения пользователю

Логин должен быть уникальным в пределах базы. Полное имя — нет: два «Петрова А.» вполне могут существовать одновременно.

Не стройте логику на сравнении с полным именем. Его меняют при смене фамилии, исправлении опечатки, и проверка Если ПолноеИмяПользователя() = "Петров" молча перестанет срабатывать. Для условий берите логин, а ещё лучше — роль или ссылку на справочник.

Когда список пользователей пуст

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

Справочник «Пользователи» в типовых конфигурациях

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

// На сервере
ТекущийПользователь = Пользователи.ТекущийПользователь();

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

Возвращается СправочникСсылка.Пользователи. Её можно сразу записать в реквизит:

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

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

  • 👤 Пользователи.АвторизованныйПользователь() — вернёт ссылку на пользователя или внешнего пользователя, если в базу зашёл контрагент через портал;
  • 🛡 Пользователи.ЭтоПолноправныйПользователь() — проверка полных прав без обращения к ролям по имени;
  • 🔎 Пользователи.НайтиПоИмени() и аналоги — поиск в справочнике по логину.

Если внешние пользователи в базе включены, Пользователи.ТекущийПользователь() под внешним пользователем вызовет исключение. В коде, который могут выполнить обе категории, используйте АвторизованныйПользователь().

Параметр сеанса ТекущийПользователь

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

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

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

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

&НаСервереБезКонтекста
Функция ОписаниеСеанса()

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

    Возврат СтрШаблон("%1 | %2 | %3 | сеанс №%4 с %5",
        Сеанс.Пользователь.Имя,
        Сеанс.ИмяКомпьютера,
        Сеанс.ИмяПриложения,
        Сеанс.НомерСеанса,
        Формат(Сеанс.НачалоСеанса, "ДФ='дд.ММ.гггг ЧЧ:мм'"));

КонецФункции
СвойствоЧто содержит
ПользовательОбъект ПользовательИнформационнойБазы
ИмяКомпьютераКомпьютер, с которого подключились
ИмяПриложенияТип подключения: тонкий клиент, веб-клиент, фоновое задание, COM-соединение
НомерСеансаНомер, по которому сеанс видно в консоли кластера
НачалоСеансаДата и время входа

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

ИмяКомпьютера в веб-клиенте покажет не машину пользователя, а сервер, через который идёт соединение. Для аудита рабочих мест на это поле в веб-клиенте полагаться нельзя.

Текущий пользователь в запросе и отчёте на СКД

В языке запросов нет функции «текущий пользователь». Значение передают параметром:

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

Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
Выборка = Запрос.Выполнить().Выбрать();

Имя документа и реквизита в примере условные — подставьте свои из конфигурации.

Отбор по пользователю в СКД

В схеме компоновки данных добавьте в запрос параметр &ТекущийПользователь. Затем заполните его в модуле объекта отчёта до вывода:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

    КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
        "ТекущийПользователь", Пользователи.ТекущийПользователь());

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

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

Ограничение доступа на уровне записей

Если задача — чтобы каждый видел только свои документы, отбор в отчёте не защищает. Его обходят через любой другой список. Правильный путь — ограничение доступа на уровне записей (RLS) в роли. В тексте ограничения параметр сеанса указывается через амперсанд: ГДЕ Ответственный = &ТекущийПользователь. В типовых конфигурациях ограничения строятся механизмом БСП, и правка ролей там — работа разработчика, а не настройка.

Фоновые задания, веб-клиент и внешнее соединение

Здесь чаще всего получают «не того» пользователя.

  • ⚙️ Фоновое задание, запущенное из кода, выполняется от имени того, кто его запустил. ИмяПользователя() внутри вернёт логин инициатора.
  • 🕒 Регламентное задание выполняется от имени пользователя, указанного в его настройках. Если поле пустое, результат зависит от базы: при отсутствии списка пользователей имя будет пустым. Задайте пользователя явно — так проще читать журнал регистрации.
  • 🌐 Веб-клиент и тонкий клиент — серверные объекты недоступны. ИмяПользователя() и ПолноеИмяПользователя() работают на клиенте, а за объектом ПользовательИнформационнойБазы идите в серверный вызов.
  • 🔌 Внешнее соединение и COM — пользователь берётся из строки подключения (Usr=). Под ним и выполняется весь код.
  • 📱 HTTP-сервисы — пользователь определяется по авторизации при публикации на веб-сервере.

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

Как передать «настоящего» инициатора в регламентное задание, которое работает под служебным логином? Сохраните ссылку в параметры задания или в регистр при постановке в очередь. Внутри задания определять «кто нажал кнопку» уже поздно.

Где выполняется ваш код?

Готовые примеры и типичные ошибки

Пишем, кто изменил документ

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

Проверка ОбменДанными.Загрузка нужна, чтобы при обмене не затирать автора из базы-источника логином служебного пользователя обмена.

Безопасное получение ссылки с обработкой ошибок

Функция ТекущийПользовательБезопасно() Экспорт

    Попытка
        Возврат Пользователи.АвторизованныйПользователь();
    Исключение
        ЗаписьЖурналаРегистрации("Определение пользователя",
            УровеньЖурналаРегистрации.Ошибка, , ,
            ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        Возврат Справочники.Пользователи.ПустаяСсылка();
    КонецПопытки;

КонецФункции

Пустая ссылка вместо исключения позволяет документу записаться, а причина остаётся в журнале регистрации.

Ошибки, которые встречаются чаще всего

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

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

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