Кто сейчас работает в базе: имя, роли и учётка Windows из кода 1С
Содержание
Чтобы определить текущего пользователя в 1С 8.3, на сервере вызовите ПользователиИнформационнойБазы.ТекущийПользователь(): вернётся объект с именем, полным именем, ролями и привязкой к учётке Windows. Если нужна только строка с именем входа, хватит глобальной функции ИмяПользователя(), она работает и на клиенте.
В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) чаще нужен не пользователь информационной базы, а ссылка на элемент справочника «Пользователи». Её даёт Пользователи.ТекущийПользователь(). Функции ГлобальныйКонтекст.ТекущийПользователь() в платформе 8.3 нет: обращение к глобальному контексту идёт без префикса.
Три способа узнать пользователя и чем они отличаются
Платформа и библиотека стандартных подсистем дают разные «уровни» пользователя. Путаница между ними — главный источник ошибок в доработках.
| Способ | Что возвращает | Где доступен |
|---|---|---|
ИмяПользователя() | Строка — имя для входа | Клиент и сервер |
ПолноеИмяПользователя() | Строка — полное имя (обычно ФИО) | Клиент и сервер |
ПользователиИнформационнойБазы.ТекущийПользователь() | Объект ПользовательИнформационнойБазы | Сервер, толстый клиент, внешнее соединение |
Пользователи.ТекущийПользователь() (БСП) | СправочникСсылка.Пользователи | Сервер |
ПользователиКлиент.ТекущийПользователь() (БСП) | СправочникСсылка.Пользователи | Клиент |
Простое правило выбора:
- 🔹 Нужно вывести имя в заголовок или сообщение —
ИмяПользователя()илиПолноеИмяПользователя(). - 🔹 Нужно проверить роли, способ входа, логин ОС — объект пользователя ИБ.
- 🔹 Нужно записать «Ответственного» в документ или отобрать данные по пользователю — ссылка на справочник из БСП.
Пример на сервере:
&НаСервере
Процедура ПоказатьПользователяНаСервере()
ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Сообщить("Имя: " + ТекПользователь.Имя);
Сообщить("Полное имя: " + ТекПользователь.ПолноеИмя);
Сообщить("Идентификатор: " + Строка(ТекПользователь.УникальныйИдентификатор));
КонецПроцедуры
УникальныйИдентификатор пользователя ИБ не меняется при переименовании. Если храните связь «пользователь → настройка» в своём регистре, ключом берите его, а не имя.
Имя и полное имя: что куда попадает
У пользователя информационной базы два текстовых поля. Их заполняет администратор в списке пользователей (в Конфигураторе — Администрирование → Пользователи, в типовых на БСП — карточка в разделе Администрирование → Настройки пользователей и прав → Пользователи).
- 👤 Имя — логин, который пользователь выбирает или вводит в окне входа. Уникально в базе. Его возвращает
ИмяПользователя()и свойствоИмя. - 🪪 Полное имя — человекочитаемое представление, обычно «Иванова Мария Петровна». Его возвращает
ПолноеИмяПользователя()и свойствоПолноеИмя.
На практике логин часто короткий («Иванова», «buh1»), а полное имя — ФИО целиком. В журнале регистрации и в списке активных пользователей платформа показывает именно имя (логин).
Что важно для кода:
- Не сравнивайте пользователей по полному имени: оно не уникально, двух «Ивановых А.» в базе может быть сколько угодно.
- Имя тоже меняется — администратор переименовал учётку, и проверка
Если ИмяПользователя() = "Петров"молча перестала работать. - Для проверки прав используйте роли, а не имена (см. раздел ниже).
Пустой список пользователей
Если в базе не заведено ни одного пользователя, вход идёт без окна авторизации. Тогда ИмяПользователя() вернёт пустую строку, а ТекущийПользователь() — пользователя с пустым именем. Учитывайте это в коде, который пишет имя в реквизиты или журнал:
ИмяДляЖурнала = ИмяПользователя();
Если ПустаяСтрока(ИмяДляЖурнала) Тогда
ИмяДляЖурнала = "<не задан>";
КонецЕсли;
Логин Windows и домен текущего пользователя
Здесь две разные задачи: узнать, к какой учётке ОС привязан пользователь 1С, и узнать, под какой учётной записью Windows реально запущен клиент.
Привязка пользователя 1С к учётке ОС
При аутентификации операционной системы в карточке пользователя ИБ указывается пользователь ОС в формате \\ДОМЕН\логин. Из кода он читается так:
&НаСервере
Функция ЛогинОСТекущегоПользователя()
ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Результат = Новый Структура("Включена, Домен, Логин", Ложь, "", "");
Результат.Включена = ТекПользователь.АутентификацияОС;
ПолноеИмяОС = ТекПользователь.ПользовательОС; // например, \\CORP\ivanova
Если ПустаяСтрока(ПолноеИмяОС) Тогда
Возврат Результат;
КонецЕсли;
ПолноеИмяОС = СтрЗаменить(ПолноеИмяОС, "\\", "");
Части = СтрРазделить(ПолноеИмяОС, "\", Ложь);
Если Части.Количество() = 2 Тогда
Результат.Домен = Части[0];
Результат.Логин = Части[1];
Иначе
Результат.Логин = ПолноеИмяОС;
КонецЕсли;
Возврат Результат;
КонецФункции
Для \\CORP\ivanova функция вернёт домен CORP и логин ivanova. Если аутентификация ОС не настроена, строка пустая, и структура вернётся с пустыми полями.
Под кем реально запущен клиент
Привязка в карточке — это то, что настроил администратор. А фактическая учётка Windows на компьютере пользователя видна только с клиента. На Windows для этого подходит COM-объект WScript.Network:
&НаКлиенте
Процедура ПоказатьУчеткуWindows(Команда)
Попытка
Сеть = Новый COMОбъект("WScript.Network");
Сообщить("Windows: " + Сеть.UserDomain + "\" + Сеть.UserName);
Сообщить("Компьютер: " + Сеть.ComputerName);
Исключение
Сообщить("COM недоступен: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Этот код работает только в клиенте под Windows. В веб-клиенте, на Linux и macOS COM-объектов нет, поэтому вызов всегда оборачивайте в Попытка.
Имя компьютера без COM даёт глобальная функция ИмяКомпьютера(). Если вызвать её на сервере, вернётся имя сервера, а не рабочей станции, — частая ловушка в клиент-серверном варианте.
Роли и права текущего пользователя
Проверять «кто это» по имени — плохая практика. Правильно спрашивать «что ему можно».
Проверка роли
Глобальная функция РольДоступна() отвечает, есть ли у текущего пользователя роль:
Если РольДоступна("ПолныеПрава") Тогда
// разрешаем служебную операцию
КонецЕсли;
// вариант с объектом метаданных — опечатка в имени выявится сразу
Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
// ...
КонецЕсли;
Список всех ролей пользователя ИБ лежит в коллекции Роли:
&НаСервере
Процедура ВывестиРоли()
ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Для Каждого Роль Из ТекПользователь.Роли Цикл
Сообщить(Роль.Имя + " — " + Роль.Синоним);
КонецЦикла;
КонецПроцедуры
Проверка права на объект
Когда важна не роль, а конкретное действие, используйте ПравоДоступа():
Если ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг) Тогда
// показываем кнопку «Исправить»
КонецЕсли;
Это устойчивее к изменениям: роли могут переименовать или раздробить, а право на объект останется.
Права другого пользователя
ПравоДоступа() принимает третьим параметром пользователя ИБ или роль. Это удобно в обработках администратора: проверить, увидит ли сотрудник документ, не входя под его учёткой.
&НаСервере
Функция МожетИзменятьРеализации(ИмяВхода)
Проверяемый = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяВхода);
Если Проверяемый = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Возврат ПравоДоступа("Изменение",
Метаданные.Документы.РеализацияТоваровУслуг, Проверяемый);
КонецФункции
Функция отвечает только про права ролей. Ограничения на уровне записей (RLS) и запреты, которые типовая конфигурация проверяет своим кодом, она не учитывает.
Что даёт БСП
В типовых конфигурациях удобнее функции подсистемы «Пользователи»:
- ✅
Пользователи.ЭтоПолноправныйПользователь()— полные права с учётом настроек БСП. - ✅
Пользователи.ТекущийПользователь()— ссылка на элемент справочника «Пользователи». - ✅
Пользователи.АвторизованныйПользователь()— ссылка на пользователя или внешнего пользователя.
Если в базе работают внешние пользователи (клиенты, контрагенты через личный кабинет), берите АвторизованныйПользователь(). ТекущийПользователь() под внешним пользователем вызовет исключение.
В привилегированном режиме код читает и пишет данные без проверки прав, но РольДоступна() по-прежнему отвечает про роли реального пользователя. Это позволяет внутри привилегированного блока решать, что показать человеку.
Клиент, веб-клиент и мобильное приложение
Где выполняется код, определяет, какой функцией пользоваться.
| Контекст | Что работает | Чего нет |
|---|---|---|
| Тонкий клиент Windows | ИмяПользователя(), ПолноеИмяПользователя(), РольДоступна(), COM | ПользователиИнформационнойБазы |
| Веб-клиент | ИмяПользователя(), ПолноеИмяПользователя(), РольДоступна() | COM, ПользователиИнформационнойБазы |
| Сервер | Всё, включая объект пользователя ИБ | COM к рабочей станции пользователя |
| Мобильное приложение (автономное) | Функции глобального контекста | Своих пользователей ИБ обычно нет — имя пустое |
Отсюда типовой шаблон для управляемой формы: всё, что связано с объектом пользователя, — в серверной процедуре без контекста, на клиент возвращать готовые значения.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Сведения = СведенияОПользователе();
Заголовок = "Работает: " + Сведения.ПолноеИмя;
Элементы.ГруппаАдмин.Видимость = Сведения.Администратор;
КонецПроцедуры
&НаСервереБезКонтекста
Функция СведенияОПользователе()
ТекПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Сведения = Новый Структура;
Сведения.Вставить("ПолноеИмя", ТекПользователь.ПолноеИмя);
Сведения.Вставить("Администратор", РольДоступна("ПолныеПрава"));
Возврат Сведения;
КонецФункции
Серверный вызов &НаСервереБезКонтекста не тащит на сервер данные формы, поэтому он дешевле, чем &НаСервере.
Видимость кнопок по роли лучше задавать в самой форме через свойство «Роли» у элемента или командного интерфейса. Код нужен, когда условие сложнее простой проверки роли.
Не вызывайте сервер ради имени в цикле
Каждое обращение с клиента к серверной функции — отдельный серверный вызов. Если имя или флаг «администратор» нужны в нескольких местах формы, получите их один раз в ПриСозданииНаСервере и положите в реквизит формы. В общих модулях для той же цели подходит модуль с повторным использованием возвращаемых значений «На время сеанса»: функция выполнится один раз, дальше результат берётся из кеша.
Мобильное приложение
В автономном мобильном приложении база локальная, и пользователей ИБ там чаще всего не заводят. ИмяПользователя() вернёт пустую строку. Пользователя приложения определяют своими средствами: при первом запуске — авторизация на центральной базе, логин хранится в константе или настройке.
Мобильный клиент, подключённый к серверной базе, ведёт себя как тонкий клиент: вход с логином и паролем, функции глобального контекста работают как обычно.
Пользователь в журнале регистрации и в своих логах
При записи в журнал регистрации пользователя указывать не нужно: платформа сама проставляет текущего пользователя, компьютер, приложение и сеанс.
ЗаписьЖурналаРегистрации(
"МояОбработка.ЗагрузкаЦен",
УровеньЖурналаРегистрации.Информация,
Метаданные.Справочники.Номенклатура,
,
"Загружено позиций: " + Формат(КоличествоСтрок, "ЧГ=0"));
Имя события пишите с префиксом своей подсистемы, через точку. Так отбор в журнале (Администрирование → Обслуживание → Журнал регистрации в типовых) быстро отделит ваши записи от системных.
Прочитать из кода, что делал конкретный пользователь, можно функцией ВыгрузитьЖурналРегистрации() с отбором:
&НаСервере
Функция СобытияПользователяЗаСегодня()
Отбор = Новый Структура;
Отбор.Вставить("Пользователь", ПользователиИнформационнойБазы.ТекущийПользователь());
Отбор.Вставить("ДатаНачала", НачалоДня(ТекущаяДатаСеанса()));
События = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(События, Отбор);
Возврат События.Количество();
КонецФункции
На больших журналах выгрузка без отбора по дате идёт долго, поэтому период задавайте всегда.
Сведения о текущем сеансе
Если пишете собственный лог в регистр сведений , кроме пользователя полезно сохранить номер сеанса и компьютер. Их даёт текущий сеанс информационной базы:
&НаСервере
Процедура ЗаписатьВЛог(ТекстСобытия)
Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
Запись = РегистрыСведений.ЛогОпераций.СоздатьМенеджерЗаписи();
Запись.Период = ТекущаяДатаСеанса();
Запись.Пользователь = Пользователи.ТекущийПользователь();
Запись.Компьютер = Сеанс.ИмяКомпьютера;
Запись.НомерСеанса = Сеанс.НомерСеанса;
Запись.Событие = ТекстСобытия;
Запись.Записать();
КонецПроцедуры
Регистр ЛогОпераций и его поля здесь — пример, создайте их под свою задачу. Сеанс.ИмяКомпьютера — это рабочая станция пользователя, в отличие от ИмяКомпьютера() на сервере.
Автор документа
Типовая задача — запомнить, кто создал документ. Ссылку на пользователя пишут в реквизит при первой записи:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ЭтоНовый() И Не ЗначениеЗаполнено(Автор) Тогда
Автор = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
Проверка Не ЗначениеЗаполнено нужна для загрузки и обмена: если автор пришёл из другой базы, перезаписывать его не следует. Для данных, приходящих через обмен, учтите и ОбменДанными.Загрузка, если обработчики при загрузке у вас отключаются.
Частые ошибки в коде
Частые вопросы
Можно ли узнать пользователя из запроса, без кода на встроенном языке?
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь()).Как получить список всех, кто сейчас в базе?
ПолучитьСеансыИнформационнойБазы(): у каждого сеанса есть свойства Пользователь, ИмяКомпьютера, ИмяПриложения, НачалоСеанса.Обновится ли имя, если администратор переименовал пользователя во время работы?
Где в БСП хранится ссылка на текущего пользователя?
ТекущийПользователь. Читать его напрямую не нужно: функция Пользователи.ТекущийПользователь() делает это за вас и сама проверяет, что сеанс открыт не под внешним пользователем.Почему администратор видит пустое ФИО?
ПолноеИмяПользователя() начнёт возвращать ФИО.