Кто сейчас работает в базе: имя, роли и ссылка на пользователя из кода 1С 8.3

· 9 мин

Содержание

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

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

Что вернёт каждый способ: короткая шпаргалка

Прежде чем писать код, определитесь с типом результата. Путаница здесь — главный источник ошибок.

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

Строку имени нельзя записать в реквизит типа «СправочникСсылка.Пользователи». Если в документе есть реквизит «Ответственный», вам нужна ссылка из БСП, а не ИмяПользователя().

Глобальный контекст: функции ИмяПользователя и ПолноеИмяПользователя

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

Логин = ИмяПользователя();          // например, "Иванова"
ФИО   = ПолноеИмяПользователя();    // например, "Иванова Ольга Петровна"

Сообщить("В базе работает: " + ФИО + " (" + Логин + ")");

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

  • 🔑 ИмяПользователя() — поле «Имя» из списка пользователей. Его человек вводит при входе.
  • 👤 ПолноеИмяПользователя() — поле «Полное имя». Его показывают в заголовке окна и в списке активных пользователей.

Если в базе не создан ни один пользователь, обе функции вернут пустую строку. Это нормальная ситуация для файловых баз «на одного». Код, который ищет пользователя по имени, в такой базе ничего не найдёт. Предусмотрите ветку на этот случай.

Рядом с ними в глобальном контексте живут ещё две полезные функции:

  • 🖥️ ИмяКомпьютера() — имя машины, на которой выполняется код. На клиенте это компьютер сотрудника, на сервере — сервер 1С.
  • 🔢 НомерСеансаИнформационнойБазы() — номер текущего сеанса, тот же, что виден в консоли кластера.

Вместе с логином этого хватает для простого журнала действий: кто, откуда и в каком сеансе нажал кнопку.

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

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

Когда мало одного имени, берите объект пользователя информационной базы. В нём хранятся настройки входа, язык, роли и уникальный идентификатор.

&НаСервере
Процедура ЗаполнитьСведенияОПользователеНаСервере()

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

    Если ПустаяСтрока(ПользовательИБ.Имя) Тогда
        Сообщить("Список пользователей пуст, вход без авторизации");
        Возврат;
    КонецЕсли;

    Сообщить("Имя: " + ПользовательИБ.Имя);
    Сообщить("Полное имя: " + ПользовательИБ.ПолноеИмя);
    Сообщить("ID: " + Строка(ПользовательИБ.УникальныйИдентификатор));
    Сообщить("Вход через ОС: " + Формат(ПользовательИБ.АутентификацияОС, "БЛ=Нет; БИ=Да"));
    Сообщить("Пользователь Windows: " + ПользовательИБ.ПользовательОС);

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

Свойства, которые чаще всего нужны в коде:

СвойствоТипЗачем пригодится
ИмяСтрокаЛогин для поиска и логов
ПолноеИмяСтрокаПодпись в печатных формах
УникальныйИдентификаторУникальныйИдентификаторНадёжная связь с вашими справочниками
РолиКоллекция ролейСписок назначенных ролей
АутентификацияСтандартная, АутентификацияОСБулевоКак пользователь входит в базу
ПользовательОССтрокаУчётная запись Windows вида \\ДОМЕН\Логин
ЯзыкОбъект метаданныхЯзык интерфейса

Имя пользователь может поменять, полное имя — тем более. Для связи с вашими данными храните УникальныйИдентификатор, а не строку имени. Так устроена связь в БСП: у элемента справочника «Пользователи» есть реквизит ИдентификаторПользователяИБ.

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

Пользователь из объекта сеанса

Иногда вместе с пользователем нужно знать, откуда он зашёл: с какого компьютера, каким клиентом, во сколько. Для этого есть объект сеанса.

&НаСервере
Функция ОписаниеТекущегоСеанса()

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

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

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

Что даёт объект СеансИнформационнойБазы:

  • 🖥️ ИмяКомпьютера — имя машины клиента;
  • 📱 ИмяПриложения — тип клиента: ThinClient, WebClient, 1CV8 (толстый клиент), BackgroundJob, COMConnection и другие; ПредставлениеПриложения() превращает их в читаемый текст;
  • ⏱ НачалоСеанса — дата и время входа;
  • 🔢 НомерСеанса и НомерСоединения — для сверки с консолью кластера.

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

&НаСервере
Функция КтоЕщёВБазе()

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

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

Сеанс — это одно подключение. Один сотрудник с двумя открытыми окнами 1С даст два сеанса с одинаковым пользователем. Считая «занятые» лицензии, учитывайте это.

Как получить пользователя в толстом и тонком клиенте

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

Где выполняется кодИмяПользователя()ПользователиИнформационнойБазы
Толстый клиент, обычное приложение✅✅ прямо в модуле формы
Толстый клиент, управляемое приложение✅✅
Тонкий клиент✅❌ только через вызов сервера
Веб-клиент✅❌ только через вызов сервера
Сервер, фоновое задание, внешнее соединение✅✅

В тонком и веб-клиенте менеджер ПользователиИнформационнойБазы недоступен. Правильная схема для управляемой формы:

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

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

Обратите внимание на &НаСервереБезКонтекста. Данные формы этой функции не нужны, и платформа не будет гонять их на сервер. Сам объект ПользовательИнформационнойБазы на клиент не передаётся, поэтому возвращайте строку, идентификатор или структуру с нужными полями.

Если нужно только имя для подписи в форме, сервер вообще не нужен — ПолноеИмяПользователя() работает прямо на клиенте.

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

В БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на Библиотеке стандартных подсистем пользователь — это ещё и элемент справочника «Пользователи». Именно его ставят в реквизиты «Ответственный», «Автор», «Менеджер».

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

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

Клиентский вариант берёт значение из параметров, полученных при запуске, и не делает серверный вызов. На сервере ссылку также хранит параметр сеанса ПараметрыСеанса.ТекущийПользователь.

Заполнение реквизита при создании документа обычно пишут в модуле объекта:

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

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

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

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

Роли и права доступа текущего пользователя

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

РольДоступна() — проверяет, назначена ли роль текущему пользователю. Работает и на клиенте, и на сервере.

Если РольДоступна("ПолныеПрава") Тогда
    Элементы.Себестоимость.Видимость = Истина;
КонецЕсли;

// Надёжнее — через метаданные: опечатка в имени роли сразу вызовет ошибку
Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
    // ...
КонецЕсли;

ПравоДоступа() — проверяет конкретное право на объект метаданных, с учётом всех ролей сразу. Вызывайте на сервере.

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

Когда что выбирать:

  • 🎯 ПравоДоступа() — если важен результат «может или нет». Не зависит от того, какой ролью право выдано.
  • 🏷️ РольДоступна() — если логика привязана к конкретной роли, например «Главный бухгалтер».
  • 📋 ПользовательИБ.Роли.Содержит(Метаданные.Роли.ИмяРоли) — если проверяете не текущего, а другого пользователя (нужны административные права).

В БСП есть свои обёртки: Пользователи.ЭтоПолноправныйПользователь() и Пользователи.РолиДоступны("Роль1, Роль2"). Они учитывают особенности библиотеки, поэтому в типовых конфигурациях лучше вызывать их.

В привилегированном режиме (УстановитьПривилегированныйРежим(Истина) или общий модуль с флагом «Привилегированный») проверки прав на сервере пропускаются. ПравоДоступа() в таком коде не говорит ничего о реальных правах сотрудника. Проверяйте права до входа в привилегированный режим.

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

Ошибки и скорость: на что обратить внимание

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

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

Что помогает:

  1. Получите пользователя один раз до цикла и сохраните в переменной.
  2. Для значений, которые не меняются за сеанс, используйте общий модуль с повторным использованием возвращаемых значений «На время сеанса». Первый вызов посчитает, остальные возьмут результат из кэша.
  3. В формах получайте всё нужное в ПриСозданииНаСервере и складывайте в реквизит формы. Клиентский код потом читает реквизит без обращения к серверу.
  4. В запросах не подставляйте пользователя строкой. Передавайте ссылку или идентификатор параметром.
// Общий модуль «ПользовательПовтИсп»: Сервер, Повторное использование — На время сеанса
Функция РолиТекущегоПользователя() Экспорт
    Роли = Новый Массив;
    Для Каждого Роль Из ПользователиИнформационнойБазы.ТекущийПользователь().Роли Цикл
        Роли.Добавить(Роль.Имя);
    КонецЦикла;
    Возврат Новый ФиксированныйМассив(Роли);
КонецФункции

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

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

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