Текущий пользователь в коде 1С 8.3: имя, ссылка, УИД и роли
Содержание
Чтобы узнать текущего пользователя 1С в коде, хватает одной строки: ИмяПользователя() вернёт имя, под которым запущен сеанс, а ПользователиИнформационнойБазы.ТекущийПользователь() — сам объект пользователя с УИД и ролями. В типовых конфигурациях на БСП ссылку на элемент справочника «Пользователи» даёт Пользователи.ТекущийПользователь().
Частое заблуждение — искать для этого функцию вроде SessionUser(). В платформе 1С:Предприятие 8.3 такой нет. Есть три уровня: строка с именем, объект пользователя информационной базы и ссылка на справочник конфигурации. Какой нужен, зависит от задачи и от того, где выполняется код — на клиенте или на сервере.
Три уровня «пользователя» в 1С
Начинающие разработчики часто путают три разные сущности. Из-за этого код работает в одной базе и падает в другой.
| Что это | Где хранится | Как получить |
|---|---|---|
| 🔤 Имя пользователя (строка) | Список пользователей ИБ в Конфигураторе | ИмяПользователя(), ПолноеИмяПользователя() |
| 🧩 Пользователь информационной базы | Платформа, раздел Администрирование → Пользователи в Конфигураторе | ПользователиИнформационнойБазы.ТекущийПользователь() |
| 📇 Элемент справочника «Пользователи» | Данные конфигурации (БСП) | Пользователи.ТекущийПользователь() |
Пользователь ИБ — это учётная запись платформы: логин, пароль, роли, способ аутентификации. Элемент справочника — обычные данные, на которые ссылаются документы в реквизите «Ответственный» или «Автор». БСП связывает их через реквизит ИдентификаторПользователяИБ в справочнике.
Если нужно записать автора в документ — берите ссылку на справочник. Если нужно проверить роль или вывести логин — хватит платформенных функций.
Функции глобального контекста: ИмяПользователя() и ПолноеИмяПользователя()
Самый простой способ узнать текущего пользователя 1С программно. Обе функции доступны и на клиенте, и на сервере, вызов сервера не нужен.
Имя = ИмяПользователя(); // "Иванов"
ПолноеИмя = ПолноеИмяПользователя(); // "Иванов Пётр Сергеевич"
Сообщить("Сеанс запущен пользователем: " + ПолноеИмя);
Английские синонимы для кода на английском синтаксисе — UserName() и UserFullName().
Что важно помнить:
- 🔹
ИмяПользователя()возвращает то, что пользователь вводит при входе (поле «Имя» в списке пользователей). - 🔹
ПолноеИмяПользователя()— поле «Полное имя». Если его не заполнили, вернётся пустая строка или то же значение, что заполнил администратор. - 🔹 Если в базе нет ни одного пользователя, обе функции вернут пустую строку
"".
Последний пункт — частая причина ошибок в отладке. Разработчик работает в пустой базе без пользователей, код ищет пользователя по имени "" и ничего не находит.
Объект ПользовательИнформационнойБазы через ТекущийПользователь()
Когда нужен не просто логин, а УИД, список ролей или способ входа, получите объект пользователя информационной базы.
&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()
ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Результат = Новый Структура;
Результат.Вставить("Имя", ТекПользователь.Имя);
Результат.Вставить("ПолноеИмя", ТекПользователь.ПолноеИмя);
Результат.Вставить("УИД", Строка(ТекПользователь.УникальныйИдентификатор));
Результат.Вставить("ВходПоПаролю", ТекПользователь.АутентификацияСтандартная);
Результат.Вставить("ВходЧерезОС", ТекПользователь.АутентификацияОС);
Результат.Вставить("ПользовательОС", ТекПользователь.ПользовательОС);
Возврат Результат;
КонецФункции
Менеджер ПользователиИнформационнойБазы (в английском синтаксисе — InfoBaseUsers) недоступен в тонком клиенте и веб-клиенте. Поэтому функция объявлена с директивой &НаСервереБезКонтекста, а в форму возвращается структура. Сам объект пользователя на клиент не передаётся.
Зачем нужен УИД
Имя пользователя можно переименовать, а УникальныйИдентификатор остаётся прежним. Если вы храните настройки, логи или связи с внешней системой, привязывайтесь к УИД, а не к имени.
УИД = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
В базе без пользователей ТекущийПользователь() возвращает объект с пустым именем и нулевым УИД 00000000-0000-0000-0000-000000000000. Проверяйте это, прежде чем искать по УИД в справочниках.
Ссылка на пользователя в типовых конфигурациях (БСП)
В БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на Библиотеке стандартных подсистем текущего пользователя получают через общие модули подсистемы «Пользователи».
// На сервере
ТекущийПользователь = Пользователи.ТекущийПользователь();
// На клиенте, без вызова сервера
ТекущийПользователь = ПользователиКлиент.ТекущийПользователь();
Обе функции возвращают СправочникСсылка.Пользователи. Именно её записывают в реквизиты «Ответственный», «Автор», «Менеджер».
Клиентский вариант берёт значение из параметров, которые БСП передаёт на клиент при запуске. Поэтому он работает без серверного вызова, и его можно смело использовать в обработчиках формы.
Внешние пользователи
Если в базе включены внешние пользователи (например, личный кабинет контрагента), Пользователи.ТекущийПользователь() для них вызовет исключение. Используйте Пользователи.АвторизованныйПользователь(): он вернёт ссылку либо на справочник «Пользователи», либо на «Внешние пользователи».
Авторизованный = Пользователи.АвторизованныйПользователь();
Если ТипЗнч(Авторизованный) = Тип("СправочникСсылка.ВнешниеПользователи") Тогда
// логика для внешнего пользователя
КонецЕсли;
Своя конфигурация без БСП
В самописной конфигурации нет модуля Пользователи. Сопоставьте пользователя ИБ с элементом справочника сами — по сохранённому УИД:
&НаСервере
Функция СсылкаТекущегоПользователя()
УИД = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Пользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ = &УИД";
Запрос.УстановитьПараметр("УИД", УИД);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Ссылка;
КонецЕсли;
Возврат Справочники.Пользователи.ПустаяСсылка();
КонецФункции
Здесь предполагается, что в справочнике есть реквизит ИдентификаторПользователяИБ типа УникальныйИдентификатор. Заполняйте его при создании пользователя.
💡 Чтобы не выполнять запрос при каждом обращении, вынесите функцию в общий серверный модуль с повторным использованием возвращаемых значений «На время сеанса». Ещё вариант — параметр сеанса, который заполняется в УстановкаПараметровСеанса модуля сеанса. Так устроено и в БСП: там есть параметр сеанса ТекущийПользователь.
Где выполняется код: клиент или сервер
Ошибки вида Процедура или функция с указанным именем не определена или Переменная не определена (ПользователиИнформационнойБазы) почти всегда означают одно: вызов написан в клиентском контексте.
| Способ | Тонкий и веб-клиент | Сервер | Толстый клиент, внешнее соединение |
|---|---|---|---|
ИмяПользователя() | ✅ | ✅ | ✅ |
ПолноеИмяПользователя() | ✅ | ✅ | ✅ |
РольДоступна() | ✅ | ✅ | ✅ |
ПользователиИнформационнойБазы | ❌ | ✅ | ✅ |
ПравоДоступа() | ❌ | ✅ | ✅ |
ПользователиКлиент.ТекущийПользователь() (БСП) | ✅ | ❌ | ✅ |
Пользователи.ТекущийПользователь() (БСП) | ❌ | ✅ | ✅ |
Правила, которые снимают большинство проблем:
- В модуле управляемой формы всё, что требует
ПользователиИнформационнойБазы, выносите в процедуру с&НаСервереБезКонтекста. Она не передаёт данные формы и работает быстрее, чем&НаСервере. - На клиент возвращайте примитивные типы или структуру, а не объект
ПользовательИнформационнойБазы. - Для простого вывода имени в заголовке формы сервер не нужен — используйте
ИмяПользователя()прямо на клиенте. - В фоновом задании текущим считается пользователь, который задание запустил. В регламентном — пользователь, указанный в его настройках; если он не указан, имя будет пустым.
Через сеанс информационной базы
Для журналирования удобно получить сведения о текущем сеансе целиком. На сервере это делает ПолучитьТекущийСеансИнформационнойБазы():
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Сообщить("Пользователь: " + Сеанс.Пользователь.Имя
+ ", приложение: " + Сеанс.ИмяПриложения
+ ", компьютер: " + Сеанс.ИмяКомпьютера
+ ", сеанс № " + Формат(Сеанс.НомерСеанса, "ЧГ=0"));
Номер сеанса без лишних объектов возвращает НомерСеансаИнформационнойБазы().
Проверка ролей и прав текущего пользователя
Узнать, кто работает, — полдела. Обычно дальше нужно решить, что ему показать.
РольДоступна()
Функция проверяет, есть ли у текущего пользователя роль. Работает и на клиенте, и на сервере.
Если РольДоступна("ПолныеПрава") Тогда
Элементы.КнопкаПерепровести.Видимость = Истина;
КонецЕсли;
// Тот же вызов с объектом метаданных — опечатка в имени не пройдёт проверку синтаксиса
Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
// ...
КонецЕсли;
Второй вариант надёжнее: если роль переименуют, ошибка всплывёт при проверке модуля, а не у пользователя.
ПравоДоступа()
Проверяет конкретное право на объект метаданных, а не роль. Это правильнее: роли в типовых конфигурациях часто перестраиваются, а право «Изменение» на документ остаётся тем же.
МожноМенять = ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг);
Функция серверная. Её можно вызвать и для другого пользователя, передав объект ПользовательИнформационнойБазы третьим параметром.
Список ролей пользователя
&НаСервереБезКонтекста
Функция РолиТекущегоПользователя()
Список = Новый Массив;
Для Каждого Роль Из ПользователиИнформационнойБазы.ТекущийПользователь().Роли Цикл
Список.Добавить(Роль.Имя);
КонецЦикла;
Возврат Список;
КонецФункции
Проверки в БСП
В типовых конфигурациях есть готовые функции модуля Пользователи:
- 🛡
Пользователи.ЭтоПолноправныйПользователь()— есть ли полные права; - 🛡
Пользователи.РолиДоступны("Роль1, Роль2")— есть ли хотя бы одна из перечисленных ролей.
Они учитывают особенности БСП, например работу в модели сервиса, поэтому в типовых конфигурациях предпочтительнее голого РольДоступна().
Проверка ролей в коде — это интерфейсная логика, а не защита. Скрытая кнопка не мешает открыть объект другим путём. Реальное ограничение доступа задают роли и ограничения на уровне записей (RLS).
Все пользователи базы: перебор и поиск
Иногда задача звучит не «кто я», а «есть ли в базе такой пользователь». Для этого у менеджера ПользователиИнформационнойБазы есть три метода:
| Метод | Что возвращает |
|---|---|
ПолучитьПользователей() | Массив всех пользователей ИБ |
НайтиПоИмени(Имя) | Пользователя или Неопределено |
НайтиПоУникальномуИдентификатору(УИД) | Пользователя или Неопределено |
Для Каждого Польз Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
Сообщить(Польз.Имя + " — " + Строка(Польз.УникальныйИдентификатор));
КонецЦикла;
Чтение списка других пользователей требует административного права. Обычный пользователь получит ошибку нарушения прав. Если перебор нужен в общем коде, выполняйте его в привилегированном режиме и только на сервере:
УстановитьПривилегированныйРежим(Истина);
Найденный = ПользователиИнформационнойБазы.НайтиПоИмени("Бухгалтер");
УстановитьПривилегированныйРежим(Ложь);
Для получения текущего пользователя административные права не нужны — ТекущийПользователь() доступен любому.
Какой способ выбрать: сравнение
| Задача | Чем решать | Где вызывать |
|---|---|---|
| Показать имя в форме или сообщении | ИмяПользователя() / ПолноеИмяПользователя() | Клиент или сервер |
| Заполнить «Ответственного» в документе (БСП) | Пользователи.ТекущийПользователь() | Сервер, ПриСозданииНаСервере или ОбработкаЗаполнения |
| То же на клиенте (БСП) | ПользователиКлиент.ТекущийПользователь() | Клиент |
| Привязать данные к учётной записи надёжно | ТекущийПользователь().УникальныйИдентификатор | Сервер |
| Скрыть кнопку по роли | РольДоступна(Метаданные.Роли.…) | Клиент или сервер |
| Проверить право на объект | ПравоДоступа() | Сервер |
| Записать в лог сеанс целиком | ПолучитьТекущийСеансИнформационнойБазы() | Сервер |
ИмяПользователя() — одна строка, работает на клиенте, без серверного вызова.Пользователи.ТекущийПользователь() на сервере или ПользователиКлиент.ТекущийПользователь() на клиенте.РольДоступна() для интерфейса, ПравоДоступа() для проверки права на объект.Подводные камни при получении пользователя
- ❌ Поиск элемента справочника по наименованию. Код
Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя())ломается, как только полное имя и логин различаются или у двух сотрудников одинаковые ФИО. Ищите по УИД. - ❌ Сравнение имён без учёта регистра. При входе регистр имени не важен, а строковое сравнение в коде регистр учитывает. Приводите обе строки через
ВРег(). - ❌ Пустая база в отладке. Без пользователей имя пустое, УИД нулевой,
РольДоступна()возвращаетИстинадля любой роли. Код, проверенный так, ведёт себя иначе в рабочей базе. - ❌ Кеширование на всё приложение. Модуль с повторным использованием «На время вызова» или переменная модуля приложения не годятся для пользовательских данных под фоновыми заданиями. Для пользователя кешируйте «На время сеанса».
- ❌ Регламентные задания без пользователя. Если в регламентном задании не указан пользователь, имя сеанса пустое и связать его с реальным сотрудником не получится. Заполняйте «Автора» явно или указывайте пользователя в настройках задания.
- ❌ Вызов
ПользователиИнформационнойБазыв модуле формы без директивы. По умолчанию код в модуле формы выполняется на клиенте, и платформа сообщит, что переменная не определена.
Можно ли получить текущего пользователя в тексте запроса?
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь()). В шаблонах RLS для этого используют параметр сеанса.Как узнать пользователя Windows, под которым запущена 1С?
ПользовательОС объекта ПользовательИнформационнойБазы хранит учётную запись ОС для входа через аутентификацию операционной системы. Если она не настроена, свойство пустое.Почему ИмяПользователя() в регламентном задании возвращает пустую строку?
Работает ли ТекущийПользователь() во внешней обработке?
Чем ИмяПользователя() отличается от ТекущийПользователь().Имя?
ИмяПользователя() доступна на клиенте и не требует серверного вызова. Объект пользователя нужен, когда кроме имени требуются УИД или роли.