Как определить текущего пользователя в 1С 8.3 программно
Содержание
Текущего пользователя в 1С 8.3 программно определяют одной строкой: ИмяПользователя() возвращает имя, под которым открыт сеанс, а ПользователиИнформационнойБазы.ТекущийПользователь() — объект пользователя целиком, с полным именем, уникальным идентификатором и списком ролей. В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3, УТ 11, ERP) вместо них берут ссылку на справочник: Пользователи.ТекущийПользователь() на сервере или ПользователиКлиент.ТекущийПользователь() на клиенте.
Какой вариант выбрать, зависит от задачи. Для записи в журнал хватит строки с именем. Для реквизита «Автор» в документе нужна ссылка на элемент справочника. Для проверки прав — функция РольДоступна(). Свойства с названием SessionUser во встроенном языке 1С нет: под этим запросом обычно ищут именно пользователя текущего сеанса, и все способы его получить собраны ниже.
Глобальные функции: имя пользователя сеанса без лишних объектов
Самый короткий путь — функции глобального контекста. Они доступны и на клиенте, и на сервере, не требуют прав администратора и работают в любой конфигурации, даже в пустой.
| Функция (рус.) | Функция (англ.) | Что возвращает |
|---|---|---|
ИмяПользователя() | UserName() | Имя для входа, строка |
ПолноеИмяПользователя() | UserFullName() | Полное имя из списка пользователей, строка |
РольДоступна(Роль) | IsInRole(Role) | Истина, если у пользователя есть роль |
НомерСеансаИнформационнойБазы() | InfoBaseSessionNumber() | Номер текущего сеанса, число |
Пример — вывести, кто сейчас работает:
&НаКлиенте
Процедура ПоказатьПользователя(Команда)
Сообщить("Вы вошли как: " + ИмяПользователя()
+ " (" + ПолноеИмяПользователя() + ")");
КонецПроцедуры
Проверка роли принимает либо объект метаданных, либо имя роли строкой:
Если РольДоступна("ПолныеПрава") Тогда
// разрешаем служебную команду
КонецЕсли;
Строковый вариант удобен на клиенте, но опечатка в имени роли не даст ошибки при проверке модуля. Если роль переименуют, условие тихо перестанет срабатывать. На сервере надёжнее РольДоступна(Метаданные.Роли.ПолныеПрава): при отсутствии роли упадёт сразу.
Ограничение у глобальных функций одно: они возвращают строки. Имя пользователя администратор может поменять в любой момент, поэтому хранить его в данных как ключ — плохая идея. Для связи с данными нужен идентификатор или ссылка.
Чем ИмяПользователя() отличается от объекта ПользовательИнформационнойБазы
Новички часто путают два уровня. Первый — пользователь информационной базы: учётная запись платформы, которую видно в Конфигураторе через Администрирование → Пользователи. Второй — элемент справочника «Пользователи» в конфигурации, если он там есть.
ИмяПользователя() работает с первым уровнем, но отдаёт только имя. ПользователиИнформационнойБазы.ТекущийПользователь() возвращает тот же первый уровень, но полностью.
| Критерий | ИмяПользователя() | ПользователиИнформационнойБазы.ТекущийПользователь() |
|---|---|---|
| Тип результата | Строка | ПользовательИнформационнойБазы |
| Где вызывается | Клиент и сервер | Сервер, толстый клиент, внешнее соединение |
| Даёт идентификатор | Нет | Да, УникальныйИдентификатор |
| Даёт роли | Нет (только проверка через РольДоступна) | Да, коллекция Роли |
| Устойчив к переименованию | Нет | Идентификатор — да |
Если код написан в тонком клиенте, объект пользователя на клиенте не получить. Вызывайте серверную функцию и возвращайте с неё только нужные значения — строку, идентификатор, булево.
&НаСервереБезКонтекста
Функция ИдентификаторТекущегоПользователя()
Возврат ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
КонецФункции
Отдельная история — внешние пользователи в конфигурациях на БСП (контрагенты, партнёры, работающие через веб-кабинет). Для платформы это такие же пользователи информационной базы, а в данных они связаны со справочником «Внешние пользователи». Поэтому в БСП есть две функции: ТекущийПользователь() вернёт ссылку только для обычного пользователя, а АвторизованныйПользователь() — для любого из двух видов.
Получаем объект ПользовательИнформационнойБазы и ссылку на справочник
Свойства объекта пользователя
После вызова ПользователиИнформационнойБазы.ТекущийПользователь() на сервере доступны основные свойства:
- 🔑
Имя— имя для входа; - 👤
ПолноеИмя— как пользователь назван в списке; - 🆔
УникальныйИдентификатор— постоянный ключ учётной записи; - 🛡️
Роли— коллекция ролей, можно перебрать или проверить черезСодержит(); - 🖥️
АутентификацияОСиПользовательОС— вход через Windows и привязанная учётная запись домена; - 🔐
АутентификацияСтандартная— вход по логину и паролю 1С.
Пример: собрать строку с ролями текущего пользователя для отладочного сообщения.
&НаСервере
Функция СписокРолейТекущегоПользователя()
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
Имена = Новый Массив;
Для Каждого Роль Из ПользовательИБ.Роли Цикл
Имена.Добавить(Роль.Имя);
КонецЦикла;
Возврат СтрСоединить(Имена, ", ");
КонецФункции
Получить себя может любой пользователь. А вот искать других — НайтиПоИмени(), НайтиПоУникальномуИдентификатору(), ПолучитьПользователей() — можно только с правом администрирования. Обычный пользователь получит исключение. Если такой поиск нужен в рабочем коде, оборачивайте его в серверную функцию с УстановитьПривилегированныйРежим(Истина).
Ссылка на элемент справочника «Пользователи»
В конфигурациях на БСП элемент справочника хранит идентификатор пользователя ИБ в реквизите ИдентификаторПользователяИБ. Вручную искать по нему не нужно — библиотека уже делает это при старте сеанса и кладёт результат в параметр сеанса.
| Где выполняется код | Что вызвать |
|---|---|
| Сервер | Пользователи.ТекущийПользователь() |
| Сервер, с учётом внешних пользователей | Пользователи.АвторизованныйПользователь() |
| Клиент | ПользователиКлиент.ТекущийПользователь() |
| Клиент, с учётом внешних пользователей | ПользователиКлиент.АвторизованныйПользователь() |
| Сервер, напрямую | ПараметрыСеанса.ТекущийПользователь |
Типичный сценарий — заполнить ответственного при создании документа:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Ответственный) Тогда
Ответственный = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
Если конфигурация самописная и справочника «Пользователи» нет, свяжите данные с учётной записью через УникальныйИдентификатор. Строковое имя для этого не годится: после переименования связь потеряется.
Сведения о сеансе: компьютер, приложение, время входа
Иногда мало знать, кто вошёл, — нужно понять откуда. Для этого есть функция ПолучитьТекущийСеансИнформационнойБазы(). Она возвращает объект сеанса, у которого есть свойство Пользователь с тем же объектом пользователя ИБ, а также:
- 💻
ИмяКомпьютера— с какой машины подключились; - 📱
ИмяПриложения— тонкий клиент, веб-клиент, фоновое задание, COM-соединение и т. д.; - 🕐
НачалоСеанса— дата и время входа; - 🔢
НомерСеанса— тот же номер, что показывает консоль кластера.
&НаСервереБезКонтекста
Функция ОписаниеСеанса()
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Возврат Сеанс.Пользователь.Имя + " с компьютера " + Сеанс.ИмяКомпьютера
+ ", вход " + Формат(Сеанс.НачалоСеанса, "ДФ='dd.MM.yyyy HH:mm'");
КонецФункции
Для перебора всех подключённых сеансов служит ПолучитьСеансыИнформационнойБазы(). Удобно, когда перед обновлением нужно показать, кто ещё сидит в базе.
Список сеансов только информирует. Завершать сеансы программно перед обновлением можно лишь после предупреждения пользователей: у тех, кто сейчас проводит документы, оборвётся работа и пропадут несохранённые изменения.
Кто «текущий пользователь» в распределённой базе и при обмене
В распределённой информационной базе (РИБ) у каждого узла свой список пользователей ИБ. Он не входит в данные конфигурации и обменом между узлами сам по себе не переносится. Поэтому ИмяПользователя() в главном узле и в филиале может вернуть разные имена для одного и того же человека, а идентификаторы учётных записей в разных узлах не совпадают, если пользователей заводили вручную.
Что из этого следует на практике:
- Связывайте документы со ссылкой на элемент справочника «Пользователи», а не с именем и не с идентификатором ИБ. Справочник — обычные данные, они уходят в обмен вместе с документами.
- Определяйте, в каком узле выполняется код, через
ПланыОбмена.ГлавныйУзел(). В главном узле функция возвращаетНеопределено, в подчинённом — ссылку на главный узел. - При загрузке данных обменом не перезаписывайте автора текущим пользователем.
Последний пункт ломает учёт чаще остальных. Обмен выполняется под какой-то учётной записью — часто служебной. Если в ПередЗаписью безусловно ставить Автор = Пользователи.ТекущийПользователь(), все пришедшие из филиала документы получат автором эту служебную запись.
Процедура ПередЗаписью(Отказ)
Если ОбменДанными.Загрузка Тогда
Возврат; // данные пришли обменом — автора не трогаем
КонецЕсли;
Если Не ЗначениеЗаполнено(Автор) Тогда
Автор = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
То же правило касается обменов с другими базами через универсальный формат: проверка ОбменДанными.Загрузка должна стоять первой строкой обработчика.
Параметры сеанса, константы и настройки пользователя
Параметр сеанса — быстрый доступ без запросов
Если в конфигурации нет БСП, удобно завести собственный параметр сеанса, например ТекущийПользователь с типом ссылки на ваш справочник. Заполняют его в модуле сеанса, в процедуре УстановкаПараметровСеанса:
Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
Ид = ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор;
Запрос = Новый Запрос(
"ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.Сотрудники
|ГДЕ ИдентификаторПользователя = &Ид");
Запрос.УстановитьПараметр("Ид", Ид);
Выборка = Запрос.Выполнить().Выбрать();
ПараметрыСеанса.ТекущийПользователь = ?(Выборка.Следующий(),
Выборка.Ссылка, Справочники.Сотрудники.ПустаяСсылка());
КонецПроцедуры
Здесь Сотрудники и ИдентификаторПользователя — имена из вашей конфигурации; замените их на свои. Параметр читается один раз за сеанс, дальше обращение к нему ничего не стоит.
Второй плюс — параметр сеанса можно использовать в ограничениях доступа на уровне записей. В тексте ограничения он пишется как &ТекущийПользователь, и пользователь видит, например, только свои документы.
В обычном запросе параметр сеанса сам не подставляется. Передайте его явно: Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь).
Константы и хранилища настроек
Константы общие для всей базы, персональные данные в них не хранят. Зато через константу удобно задать служебную учётную запись — например, «Пользователь для регламентных заданий» — и сравнивать с ней ИмяПользователя(), чтобы фоновый код вёл себя иначе, чем интерактивный.
Персональные значения хранят в ХранилищеОбщихНастроек. Методы Сохранить() и Загрузить() по умолчанию работают с настройками текущего пользователя, явно передавать имя не нужно:
ХранилищеОбщихНастроек.Сохранить("МояОбработка", "ПоследнийСклад", Склад);
Склад = ХранилищеОбщихНастроек.Загрузить("МояОбработка", "ПоследнийСклад");
Чтобы прочитать или записать настройки другого пользователя, имя передают последним параметром — но для этого нужны административные права.
Пустой пользователь, фоновые задания и ошибки
База без списка пользователей
Если в Конфигураторе список пользователей пуст, 1С пускает в базу без авторизации. В этом случае:
ИмяПользователя()возвращает пустую строку;- у объекта
ТекущийПользователь()пустыеИмяиПолноеИмя, а идентификатор состоит из нулей; - в БСП текущим становится служебный элемент справочника с наименованием вроде «<Не указан>».
Проверка на этот случай простая:
Если ПустаяСтрока(ИмяПользователя()) Тогда
// пользователи не заведены — права не проверяем, автора не пишем
КонецЕсли;
Не стройте защиту данных на проверке имени пользователя. В базе без списка пользователей у входящего полные права, и код, который «пропускает только Иванова», ничего не защищает.
Фоновые и регламентные задания
Фоновое задание, запущенное из кода, выполняется от имени того, кто его запустил. У регламентного задания пользователь задаётся в его свойствах. Если там пусто, ИмяПользователя() внутри задания может вернуть пустую строку — и код, рассчитанный на заполненное имя, упадёт или запишет пустого автора. Задайте в свойствах задания конкретную служебную запись, а в коде проверяйте результат на пустоту.
Частые вопросы
Как получить текущего пользователя в запросе?
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь()).Можно ли узнать пользователя Windows, под которым запущена 1С?
ПользовательОС объекта пользователя ИБ. Без такой привязки свойство пустое.Чем ИмяПользователя() отличается от ПолноеИмяПользователя()?
Как проверить, что пользователь — администратор?
РольДоступна(Метаданные.Роли.ПолныеПрава). В конфигурациях на БСП есть готовая функция Пользователи.ЭтоПолноправныйПользователь().Что вернёт ИмяПользователя() во внешнем соединении?
Usr). Поэтому для интеграций заводят отдельного пользователя с понятным именем.