Текущий пользователь 1С во встроенном языке, запросах и СКД

· 9 мин

Содержание

Текущего пользователя в 1С получают тремя способами. Имя строкой даёт функция ИмяПользователя(). Объект пользователя информационной базы — ПользователиИнформационнойБазы.ТекущийПользователь(). Ссылку на элемент справочника «Пользователи» в типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) возвращает Пользователи.ТекущийПользователь().

Какой из них брать, зависит от задачи. Для подписи в отчёте хватит строки. Для отбора документов по полю «Ответственный» нужна ссылка на справочник. Для проверки ролей и способа входа — объект пользователя ИБ. Всё ниже относится к платформе 1С:Предприятие 8.3 и не зависит от конкретной конфигурации, кроме мест, где упомянута БСП.

Функции глобального контекста и объект текущего пользователя

Платформа даёт несколько готовых средств. Сведём их в таблицу.

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

Простейший пример — вывести имя на клиенте:

&НаКлиенте
Процедура ПоказатьПользователя(Команда)
	Сообщить("Вы вошли как: " + ПолноеИмяПользователя());
КонецПроцедуры

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

Что есть у объекта ПользовательИнформационнойБазы

Объект даёт больше, чем имя. Полезные свойства:

  • 🆔 УникальныйИдентификатор — не меняется при переименовании, по нему надёжно связывать данные;
  • 👤 Имя и ПолноеИмя — то же, что возвращают функции глобального контекста;
  • 🔐 Роли — коллекция назначенных ролей;
  • 🪪 АутентификацияСтандартная, АутентификацияОС — какие способы входа разрешены;
  • 💻 ПользовательОС — учётная запись Windows, привязанная к пользователю, в виде \\ДОМЕН\логин;
  • 🌐 Язык — язык интерфейса пользователя.
&НаСервере
Функция ОписаниеТекущегоПользователя()
	ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
	Возврат СтрШаблон("%1 (%2), вход через ОС: %3",
		ПользовательИБ.ПолноеИмя,
		Строка(ПользовательИБ.УникальныйИдентификатор),
		?(ПользовательИБ.АутентификацияОС, "да", "нет"));
КонецФункции

Менеджер ПользователиИнформационнойБазы недоступен в тонком клиенте и веб-клиенте. Вызов из процедуры с директивой &НаКлиенте даёт ошибку Переменная не определена (ПользователиИнформационнойБазы). Переносите код в серверную процедуру формы или в общий модуль с флагом «Вызов сервера».

Сведения о сеансе

Иногда важен не сам пользователь, а его подключение: с какого компьютера он зашёл, через какой клиент, когда начал работу. Для этого есть объект сеанса:

&НаСервере
Процедура ВывестиДанныеСеанса()
	Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
	Сообщить("Компьютер: " + Сеанс.ИмяКомпьютера);
	Сообщить("Приложение: " + Сеанс.ИмяПриложения);
	Сообщить("Начало сеанса: " + Формат(Сеанс.НачалоСеанса, "ДЛФ=DT"));
КонецПроцедуры

Номер сеанса отдельно возвращает НомерСеансаИнформационнойБазы(). Удобно для журналов и диагностики, когда один пользователь открыл два окна.

Имя компьютера доступно и без объекта сеанса: функция ИмяКомпьютера() работает и на клиенте, и на сервере. Учтите, что на сервере она вернёт имя сервера 1С, а не рабочего места пользователя. Для имени рабочего места в клиент-серверном варианте берите ИмяКомпьютера из сеанса.

Пользователь ИБ, элемент справочника и учётная запись Windows

Здесь путаются чаще всего. В 1С 8.3 живут три разных «пользователя».

  1. Пользователь информационной базы. Его хранит платформа. Видно в Конфигураторе: Администрирование → Пользователи. У него логин, пароль, роли.
  2. Элемент справочника «Пользователи». Это данные конфигурации. Именно на него ссылаются реквизиты «Ответственный», «Автор», «Менеджер» в документах. В БСП элемент связан с пользователем ИБ через реквизит ИдентификаторПользователяИБ.
  3. Пользователь операционной системы. Учётная запись Windows, под которой запущен клиент. С пользователем ИБ связан только при входе через аутентификацию ОС.

Ссылка на справочник в типовой конфигурации

В конфигурациях на БСП правильный путь — программный интерфейс подсистемы «Пользователи»:

&НаСервере
Процедура ЗаполнитьОтветственного()
	Объект.Ответственный = Пользователи.ТекущийПользователь();
КонецПроцедуры

Тот же вызов есть на клиенте: ПользователиКлиент.ТекущийПользователь(). Он берёт значение из параметров, которые клиент получил при старте, и не делает лишний серверный вызов.

Если в базе есть внешние пользователи (например, личный кабинет контрагента), Пользователи.ТекущийПользователь() при их входе вызывает исключение. Для универсального кода есть Пользователи.АвторизованныйПользователь(): он вернёт ссылку либо на «Пользователи», либо на «Внешние пользователи».

Связь в обратную сторону

Когда на руках ссылка на справочник, а нужен объект платформы:

&НаСервере
Функция ПользовательИБПоСсылке(СсылкаНаПользователя)
	Ид = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаПользователя, "ИдентификаторПользователяИБ");
	Возврат ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(Ид);
КонецФункции

Метод вернёт Неопределено, если у элемента нет пользователя ИБ: например, это сотрудник, которому не дали права входа.

Не ищите элемент справочника по наименованию через НайтиПоНаименованию(ИмяПользователя()). Имя для входа и наименование элемента часто расходятся, а однофамильцы ломают поиск. Связывайте по уникальному идентификатору.

Логин Windows

Узнать учётную запись ОС на клиенте Windows можно через COM-объект:

&НаКлиенте
Функция ЛогинWindows()
	Сеть = Новый COMОбъект("WScript.Network");
	Возврат Сеть.UserDomain + "\" + Сеть.UserName;
КонецФункции

Код работает только на Windows и не работает в веб-клиенте. Если пользователь входит через аутентификацию ОС, надёжнее брать свойство ПользовательОС у объекта пользователя ИБ на сервере.

Текущий пользователь в запросах и СКД

В языке запросов нет функции «текущий пользователь». Значение передают параметром.

Обычный запрос

&НаСервере
Функция МоиНепроведённыеДокументы()
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	Реализация.Ссылка,
	|	Реализация.Дата
	|ИЗ
	|	Документ.РеализацияТоваровУслуг КАК Реализация
	|ГДЕ
	|	Реализация.Ответственный = &ТекущийПользователь
	|	И НЕ Реализация.Проведен";
	Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
	Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Параметр — ссылка на справочник, а не строка имени. Сравнение по ссылке работает по индексу и не ломается при смене ФИО.

Динамический список

Для списка на форме параметр задают при создании:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Список.Параметры.УстановитьЗначениеПараметра("ТекущийПользователь",
		Пользователи.ТекущийПользователь());
КонецПроцедуры

В тексте запроса списка (включён флаг «Произвольный запрос») условие то же: ГДЕ Таблица.Ответственный = &ТекущийПользователь.

Отчёт на СКД

В схеме компоновки параметр ТекущийПользователь появится автоматически, как только он встретится в тексте набора данных. Заполнить его проще всего в модуле объекта отчёта:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра(
		"ТекущийПользователь", Пользователи.ТекущийПользователь());
КонецПроцедуры

Чтобы пользователь не подменил значение в настройках, на закладке «Параметры» схемы снимите у параметра флаг доступности в пользовательских настройках.

Отбор в отчёте — не защита данных. Пользователь с правом на конфигуратор или на консоль запросов увидит всё. Если чужие документы показывать нельзя, нужны ограничения доступа на уровне записей (RLS), а не параметр в запросе.

Фоновые задания, регламентные задания и внешние обработки

Кто «текущий пользователь» внутри фонового кода — зависит от того, как код запущен.

Как запущен кодПод каким пользователем выполняется
ФоновыеЗадания.Выполнить() из сеанса пользователяпод тем же пользователем, что запустил задание
Регламентное задание с заполненным свойством «Пользователь»под указанным пользователем
Регламентное задание без пользователяимя может быть пустым, проверяйте это явно
Внешняя обработка, открытая пользователемпод пользователем, который её открыл
Внешнее соединение (COM)под пользователем из строки соединения

Фоновое задание помнит, кто его запустил

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

Но если задание запускают от имени одного пользователя для другого (например, менеджер ставит рассылку для отдела), передавайте адресата параметром процедуры. Текущий пользователь в фоне — это всегда тот, кто запустил.

Регламентные задания

Регламентному заданию пользователь назначается в его свойствах. В типовых конфигурациях это делается через Администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания, в карточке задания. Если пользователь не указан, рассчитывать на заполненное имя нельзя.

Защитный код в процедуре задания:

Процедура ОтправитьНапоминания() Экспорт
	Если ПустаяСтрока(ИмяПользователя()) Тогда
		ЗаписьЖурналаРегистрации("Напоминания",
			УровеньЖурналаРегистрации.Предупреждение, , ,
			"Задание запущено без пользователя, отправка пропущена");
		Возврат;
	КонецЕсли;
	// основная логика
КонецПроцедуры

Внешние обработки

Внешняя обработка не получает никаких особых прав. Она работает под пользователем, который её открыл, и видит только то, что разрешают его роли.

Если обработка подключена через справочник «Дополнительные отчёты и обработки» в безопасном режиме, включить привилегированный режим из неё нельзя. Код, который рассчитывает обойти права через УстановитьПривилегированныйРежим(Истина), в ней не сработает.

Где выполняется ваш код?

Проверка ролей и прав текущего пользователя

Получить пользователя обычно нужно, чтобы решить: показывать ли кнопку, разрешать ли действие. Для этого есть готовые функции, перебирать роли вручную не нужно.

Платформенные функции

  • ✅ РольДоступна("ПолныеПрава") — назначена ли роль текущему пользователю. Можно передать объект метаданных: РольДоступна(Метаданные.Роли.ПолныеПрава).
  • ✅ ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг) — есть ли у пользователя право на объект, с учётом всех его ролей.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	МожноМенять = ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура);
	Элементы.ФормаЗаписатьИЗакрыть.Доступность = МожноМенять;
КонецПроцедуры

ПравоДоступа предпочтительнее РольДоступна. Проверка конкретной роли ломается, когда администратор выдаёт те же права другой ролью или профилем групп доступа. Проверка права — нет.

Функции БСП

В типовых конфигурациях есть обёртки, которые учитывают устройство профилей:

  • 🛡️ Пользователи.ЭтоПолноправныйПользователь() — у пользователя полные права;
  • 🛡️ Пользователи.РолиДоступны("ДобавлениеИзменениеНоменклатуры, ПолныеПрава") — доступна хотя бы одна из перечисленных ролей.

Обе выполняются на сервере. Имена ролей в типовых меняются от релиза к релизу, поэтому перед использованием сверьте их в Конфигураторе, в ветке «Общие → Роли».

Список ролей пользователя

Для отладки или журнала можно вывести все роли:

&НаСервере
Функция РолиТекущегоПользователя()
	Результат = Новый Массив;
	Для Каждого Роль Из ПользователиИнформационнойБазы.ТекущийПользователь().Роли Цикл
		Результат.Добавить(Роль.Имя);
	КонецЦикла;
	Возврат СтрСоединить(Результат, ", ");
КонецФункции

Типичные ошибки и безопасный код

Эти ошибки регулярно всплывают при проверке чужих доработок.

1. Права определяют по имени пользователя. Конструкция Если ИмяПользователя() = "Администратор" выглядит просто, но переименование или второй администратор её ломают. Кроме того, имя — не секрет. Проверяйте права через ПравоДоступа или роли.

2. Привилегированный режим включают без нужды. Под УстановитьПривилегированныйРежим(Истина) код игнорирует права и RLS. Включайте его только на конкретную операцию и выключайте сразу после:

УстановитьПривилегированныйРежим(Истина);
Значение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "Ответственный");
УстановитьПривилегированныйРежим(Ложь);

Проверить, включён ли режим, можно функцией ПривилегированныйРежим(). Привилегированный режим не меняет пользователя: ИмяПользователя() возвращает то же имя.

3. Данные пользователя таскают с сервера при каждом действии. Каждый вызов &НаСервере из клиентской команды — обращение по сети. Получите ссылку и нужные флаги один раз в ПриСозданииНаСервере, сохраните в реквизиты формы и используйте на клиенте.

4. Текущего пользователя кешируют в общем модуле с повторным использованием на весь сеанс без учёта внешних пользователей. Если в базе есть внешние пользователи, кеш вернёт исключение при первом же их входе. Используйте Пользователи.АвторизованныйПользователь() или проверку Пользователи.ЭтоСеансВнешнегоПользователя().

5. Ответственного подставляют при каждой записи. Код Объект.Ответственный = Пользователи.ТекущийПользователь() в ПередЗаписью перезапишет автора, как только документ откроет и сохранит коллега. Заполняйте реквизит только для нового объекта: проверяйте ЭтоНовый() или пустое значение поля.

6. Пустая база без пользователей. Пока в Конфигураторе не создан ни один пользователь, ИмяПользователя() возвращает пустую строку, а проверки прав пропускают всё. Создайте хотя бы одного пользователя с полными правами, прежде чем тестировать ограничения.

Как узнать текущего пользователя без программирования?
В Конфигураторе: Администрирование → Активные пользователи. В режиме 1С:Предприятие в типовых конфигурациях откройте раздел Администрирование и найдите ссылку «Активные пользователи» — там список текущих сеансов с именами и компьютерами.
Можно ли получить текущего пользователя в правилах RLS?
Да, через параметр сеанса. В типовых на БСП параметр сеанса ТекущийПользователь заполняется при входе, а шаблоны ограничений обращаются к нему как к &ТекущийПользователь.
Почему ИмяПользователя() и ПолноеИмяПользователя() возвращают разное?
Первая возвращает имя для входа (логин), вторая — значение поля «Полное имя» из карточки пользователя ИБ. Если полное имя не заполнено, функции вернут одинаковую строку.
Как получить пользователя, который создал документ?
Платформа автора не хранит. В типовых за это отвечает реквизит «Ответственный» или «Автор», который заполняется при создании. Историю изменений ищите в журнале регистрации с отбором по данным.
Работает ли Пользователи.ТекущийПользователь() в нетиповой конфигурации?
Только если в неё встроена подсистема «Пользователи» из БСП. В «чистой» конфигурации без БСП используйте ПользователиИнформационнойБазы.ТекущийПользователь() и свой справочник с реквизитом-идентификатором.