Кто сейчас работает в базе: имя, роли и ссылка на пользователя из кода 1С 8.3
Содержание
Текущего пользователя в 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"). Они учитывают особенности библиотеки, поэтому в типовых конфигурациях лучше вызывать их.
В привилегированном режиме (УстановитьПривилегированныйРежим(Истина) или общий модуль с флагом «Привилегированный») проверки прав на сервере пропускаются. ПравоДоступа() в таком коде не говорит ничего о реальных правах сотрудника. Проверяйте права до входа в привилегированный режим.
Вторая ловушка — пустой список пользователей. В такой базе сеанс работает без ограничений, РольДоступна() вернёт Истина для любой роли. Поэтому тестируйте права, создав хотя бы двух пользователей с разными ролями.
Ошибки и скорость: на что обратить внимание
Про скорость. Сам вызов ИмяПользователя() дешёвый. Дорого обходится серверный вызов ради имени с клиента и обращение к ПользователиИнформационнойБазы в цикле по тысячам строк.
Что помогает:
- Получите пользователя один раз до цикла и сохраните в переменной.
- Для значений, которые не меняются за сеанс, используйте общий модуль с повторным использованием возвращаемых значений «На время сеанса». Первый вызов посчитает, остальные возьмут результат из кэша.
- В формах получайте всё нужное в
ПриСозданииНаСервереи складывайте в реквизит формы. Клиентский код потом читает реквизит без обращения к серверу. - В запросах не подставляйте пользователя строкой. Передавайте ссылку или идентификатор параметром.
// Общий модуль «ПользовательПовтИсп»: Сервер, Повторное использование — На время сеанса
Функция РолиТекущегоПользователя() Экспорт
Роли = Новый Массив;
Для Каждого Роль Из ПользователиИнформационнойБазы.ТекущийПользователь().Роли Цикл
Роли.Добавить(Роль.Имя);
КонецЦикла;
Возврат Новый ФиксированныйМассив(Роли);
КонецФункции
Кэш на время сеанса не узнает, что администратор поменял роли. Изменения увидит только новый сеанс. Для прав, от которых зависят деньги, кэш не используйте.