Кто сейчас работает в базе: имя, роли и учётка Windows из кода 1С

· 9 мин

Содержание

Чтобы определить текущего пользователя в 1С 8.3, на сервере вызовите ПользователиИнформационнойБазы.ТекущийПользователь(): вернётся объект с именем, полным именем, ролями и привязкой к учётке Windows. Если нужна только строка с именем входа, хватит глобальной функции ИмяПользователя(), она работает и на клиенте.

В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) чаще нужен не пользователь информационной базы, а ссылка на элемент справочника «Пользователи». Её даёт Пользователи.ТекущийПользователь(). Функции ГлобальныйКонтекст.ТекущийПользователь() в платформе 8.3 нет: обращение к глобальному контексту идёт без префикса.

Три способа узнать пользователя и чем они отличаются

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

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

Простое правило выбора:

  • 🔹 Нужно вывести имя в заголовок или сообщение — ИмяПользователя() или ПолноеИмяПользователя().
  • 🔹 Нужно проверить роли, способ входа, логин ОС — объект пользователя ИБ.
  • 🔹 Нужно записать «Ответственного» в документ или отобрать данные по пользователю — ссылка на справочник из БСП.

Пример на сервере:

&НаСервере
Процедура ПоказатьПользователяНаСервере()

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

	Сообщить("Имя: " + ТекПользователь.Имя);
	Сообщить("Полное имя: " + ТекПользователь.ПолноеИмя);
	Сообщить("Идентификатор: " + Строка(ТекПользователь.УникальныйИдентификатор));

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

УникальныйИдентификатор пользователя ИБ не меняется при переименовании. Если храните связь «пользователь → настройка» в своём регистре, ключом берите его, а не имя.

Имя и полное имя: что куда попадает

У пользователя информационной базы два текстовых поля. Их заполняет администратор в списке пользователей (в Конфигураторе — Администрирование → Пользователи, в типовых на БСП — карточка в разделе Администрирование → Настройки пользователей и прав → Пользователи).

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

На практике логин часто короткий («Иванова», «buh1»), а полное имя — ФИО целиком. В журнале регистрации и в списке активных пользователей платформа показывает именно имя (логин).

Что важно для кода:

  1. Не сравнивайте пользователей по полному имени: оно не уникально, двух «Ивановых А.» в базе может быть сколько угодно.
  2. Имя тоже меняется — администратор переименовал учётку, и проверка Если ИмяПользователя() = "Петров" молча перестала работать.
  3. Для проверки прав используйте роли, а не имена (см. раздел ниже).

Пустой список пользователей

Если в базе не заведено ни одного пользователя, вход идёт без окна авторизации. Тогда ИмяПользователя() вернёт пустую строку, а ТекущийПользователь() — пользователя с пустым именем. Учитывайте это в коде, который пишет имя в реквизиты или журнал:

ИмяДляЖурнала = ИмяПользователя();
Если ПустаяСтрока(ИмяДляЖурнала) Тогда
	ИмяДляЖурнала = "<не задан>";
КонецЕсли;

Логин 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"));

Имя события пишите с префиксом своей подсистемы, через точку. Так отбор в журнале (Администрирование → Обслуживание → Журнал регистрации в типовых) быстро отделит ваши записи от системных.

Прочитать из кода, что делал конкретный пользователь, можно функцией ВыгрузитьЖурналРегистрации() с отбором:

&НаСервере
Функция СобытияПользователяЗаСегодня()

	Отбор = Новый Структура;
	Отбор.Вставить("Пользователь", ПользователиИнформационнойБазы.ТекущийПользователь());
	Отбор.Вставить("ДатаНачала", НачалоДня(ТекущаяДатаСеанса()));

	События = Новый ТаблицаЗначений;
	ВыгрузитьЖурналРегистрации(События, Отбор);
	Возврат События.Количество();

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

На больших журналах выгрузка без отбора по дате идёт долго, поэтому период задавайте всегда.

Сведения о текущем сеансе

Если пишете собственный лог в регистр сведений , кроме пользователя полезно сохранить номер сеанса и компьютер. Их даёт текущий сеанс информационной базы:

&НаСервере
Процедура ЗаписатьВЛог(ТекстСобытия)

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

	Запись = РегистрыСведений.ЛогОпераций.СоздатьМенеджерЗаписи();
	Запись.Период = ТекущаяДатаСеанса();
	Запись.Пользователь = Пользователи.ТекущийПользователь();
	Запись.Компьютер = Сеанс.ИмяКомпьютера;
	Запись.НомерСеанса = Сеанс.НомерСеанса;
	Запись.Событие = ТекстСобытия;
	Запись.Записать();

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

Регистр ЛогОпераций и его поля здесь — пример, создайте их под свою задачу. Сеанс.ИмяКомпьютера — это рабочая станция пользователя, в отличие от ИмяКомпьютера() на сервере.

Автор документа

Типовая задача — запомнить, кто создал документ. Ссылку на пользователя пишут в реквизит при первой записи:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

	Если ЭтоНовый() И Не ЗначениеЗаполнено(Автор) Тогда
		Автор = Пользователи.ТекущийПользователь();
	КонецЕсли;

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

Проверка Не ЗначениеЗаполнено нужна для загрузки и обмена: если автор пришёл из другой базы, перезаписывать его не следует. Для данных, приходящих через обмен, учтите и ОбменДанными.Загрузка, если обработчики при загрузке у вас отключаются.

Частые ошибки в коде

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

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

Можно ли узнать пользователя из запроса, без кода на встроенном языке?
Нет, в языке запросов функции текущего пользователя нет. Передайте ссылку параметром: Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь()).
Как получить список всех, кто сейчас в базе?
На сервере функцией ПолучитьСеансыИнформационнойБазы(): у каждого сеанса есть свойства Пользователь, ИмяКомпьютера, ИмяПриложения, НачалоСеанса.
Обновится ли имя, если администратор переименовал пользователя во время работы?
Сеанс продолжит работать под прежней учёткой. Значения, закешированные в переменной модуля приложения или в параметре сеанса, обновятся только после перезапуска клиента.
Где в БСП хранится ссылка на текущего пользователя?
В параметре сеанса ТекущийПользователь. Читать его напрямую не нужно: функция Пользователи.ТекущийПользователь() делает это за вас и сама проверяет, что сеанс открыт не под внешним пользователем.
Почему администратор видит пустое ФИО?
Поле «Полное имя» в пользователе ИБ не заполнено. Заполните его в карточке, и ПолноеИмяПользователя() начнёт возвращать ФИО.