Логин, полное имя, сеанс и учётка Windows: кто сейчас работает в базе 1С
Содержание
Имя текущего пользователя в 1С 8.3 возвращает функция глобального контекста ИмяПользователя() — это логин, под которым человек вошёл в базу. Полное имя для подписей и печатных форм даёт ПолноеИмяПользователя(). Обе функции работают и на клиенте, и на сервере, специальных прав не требуют.
Типичная задача: программист дорабатывает печатную форму, и бухгалтер просит, чтобы внизу стояло «Исполнитель: Иванова А. П.», а в журнал выгрузки писался логин того, кто нажал кнопку. Ниже — какую функцию взять для каждого случая, что меняется в клиент-серверном варианте, как узнать имена других пользователей и пользователя Windows. Всё сказанное относится к платформе 8.3 и не зависит от конфигурации; отдельно отмечены приёмы для типовых решений на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11).
Логин и полное имя пользователя 1С: в чём разница
У каждого пользователя информационной базы есть два текстовых имени. Их часто путают, а потом удивляются, почему сравнение строк перестало работать.
| Что | Где задаётся | Пример | Для чего брать |
|---|---|---|---|
| Имя (логин) | поле «Имя» в списке пользователей, его вводят при входе | IvanovaAP или Иванова | проверки в коде, поиск пользователя, записи в лог |
| Полное имя | поле «Полное имя» | Иванова Анна Петровна | печатные формы, заголовки, сообщения |
| Уникальный идентификатор | присваивается платформой автоматически | 5f3c…-… | надёжная связь с пользователем, не меняется при переименовании |
Логин уникален в пределах базы. Полное имя — нет: два «Иванова А.» вполне могут существовать одновременно.
Если нужна надёжная привязка к человеку (хранить в регистре, сравнивать между сеансами), храните не строку имени, а УникальныйИдентификатор. Администратор переименует пользователя — идентификатор останется прежним.
Функции глобального контекста для получения имени пользователя
Самый короткий путь — две функции, доступные в любом модуле: форма, общий модуль, модуль объекта, обработка.
&НаКлиенте
Процедура ПоказатьКтоЯ(Команда)
Логин = ИмяПользователя();
ФИО = ПолноеИмяПользователя();
Сообщить("Логин: " + Логин + ", полное имя: " + ФИО);
КонецПроцедуры
Обе возвращают тип Строка. Вызов на сервере выглядит так же:
&НаСервереБезКонтекста
Функция ИсполнительДляПечати()
ФИО = ПолноеИмяПользователя();
Если ПустаяСтрока(ФИО) Тогда
ФИО = ИмяПользователя();
КонецЕсли;
Возврат ФИО;
КонецФункции
Проверка на пустую строку здесь не лишняя. Полное имя необязательно для заполнения, и в небольших базах его часто оставляют пустым.
Что вернётся, если пользователей в базе нет
Когда список пользователей информационной базы пуст, 1С пускает всех без авторизации. В этом случае ИмяПользователя() и ПолноеИмяПользователя() возвращают пустую строку. Код, который ищет что-то по логину, должен это учитывать — иначе запрос с отбором Автор = "" вернёт неожиданные данные.
Объект ПользовательИнформационнойБазы: всё о текущем пользователе
Строки хватает для подписи. Для остального — ролей, способа входа, идентификатора — нужен объект ПользовательИнформационнойБазы. Текущего пользователя возвращает метод менеджера:
&НаСервереБезКонтекста
Функция СведенияОТекущемПользователе()
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Сведения = Новый Структура;
Сведения.Вставить("Имя", Пользователь.Имя);
Сведения.Вставить("ПолноеИмя", Пользователь.ПолноеИмя);
Сведения.Вставить("Идентификатор", Строка(Пользователь.УникальныйИдентификатор));
Сведения.Вставить("ВходПоОС", Пользователь.АутентификацияОС);
Сведения.Вставить("ПользовательОС", Пользователь.ПользовательОС);
Возврат Сведения;
КонецФункции
Полезные свойства объекта:
- 👤
ИмяиПолноеИмя— те же строки, что дают функции глобального контекста; - 🔑
УникальныйИдентификатор— постоянный ключ пользователя; - 🖥️
АутентификацияСтандартная,АутентификацияОС— какими способами разрешён вход; - 🧑💻
ПользовательОС— привязанная учётная запись Windows в виде\\ДОМЕН\логин; - 🛡️
Роли— коллекция назначенных ролей.
Для проверки роли не нужно перебирать коллекцию. Есть функция РольДоступна("ИмяРоли"), она работает и на клиенте.
Найти другого пользователя по имени или идентификатору
У менеджера ПользователиИнформационнойБазы есть методы НайтиПоИмени(), НайтиПоУникальномуИдентификатору() и ПолучитьПользователей(). Они возвращают объекты других людей, поэтому требуют административных прав.
&НаСервере
Функция ПолноеИмяПоЛогину(Логин)
Найденный = ПользователиИнформационнойБазы.НайтиПоИмени(Логин);
Если Найденный = Неопределено Тогда
Возврат "";
КонецЕсли;
Возврат Найденный.ПолноеИмя;
КонецФункции
Если код должен работать у рядового пользователя, вынесите такую функцию в общий модуль с флагом «Привилегированный» или оберните вызов в УстановитьПривилегированныйРежим(Истина). Привилегированный режим снимает проверку прав — давайте в нём ровно столько, сколько нужно, и не возвращайте на клиент лишнего.
Пользователь в типовых конфигурациях на БСП
В Бухгалтерии 3.0, ЗУП 3.1, УТ 11 и других решениях на Библиотеке стандартных подсистем, кроме пользователя информационной базы, есть элемент справочника «Пользователи». Именно на него ссылаются реквизиты «Ответственный» и «Автор» документов.
Ссылку на текущий элемент справочника дают функции БСП:
// на сервере
ТекущийПользователь = Пользователи.ТекущийПользователь();
// на клиенте
ТекущийПользователь = ПользователиКлиент.ТекущийПользователь();
Строковый логин для отбора по реквизиту «Ответственный» не подойдёт — там ссылка. Это частая причина пустых отчётов в доработках.
Как автоматически записать автора документа
Частая доработка — поле «Автор» в собственном документе, которое заполняется само и не редактируется. Удобнее всего делать это в модуле объекта, а не в форме: тогда автор проставится и при создании документа обработкой, и при загрузке из другой базы.
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Автор) Тогда
Автор = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецПроцедуры
Обработчик ОбработкаЗаполнения срабатывает при создании нового объекта, поэтому при перезаписи старого документа автор не поменяется. Если в конфигурации нет БСП, сделайте реквизит строковым и пишите туда ИмяПользователя(), а для надёжности — отдельным реквизитом строковое представление УникальныйИдентификатор.
На форме поставьте реквизиту «Автор» свойство «Только просмотр». Тогда пользователь увидит, кто создал документ, но не сможет подменить значение вручную.
Имя пользователя в клиент-серверной базе: где выполняется код
В файловом и клиент-серверном вариантах ИмяПользователя() возвращает одно и то же — пользователя 1С, открывшего сеанс. Рабочий процесс сервера 1С запущен под служебной учётной записью Windows, но на результат функции это не влияет.
Различия начинаются с доступностью объектов на клиенте:
| Что вызываем | Тонкий клиент, веб-клиент | Сервер |
|---|---|---|
ИмяПользователя(), ПолноеИмяПользователя() | ✅ доступно | ✅ доступно |
РольДоступна() | ✅ доступно | ✅ доступно |
ПользователиИнформационнойБазы | ❌ нет | ✅ доступно |
ПолучитьСеансыИнформационнойБазы() | ❌ нет | ✅ доступно |
Если обратиться к ПользователиИнформационнойБазы в процедуре с директивой &НаКлиенте, модуль не скомпилируется. Решение — серверная функция и вызов из клиентской процедуры.
Для таких вызовов используйте &НаСервереБезКонтекста. Данные формы на сервер не передаются, вызов идёт быстрее.
Фоновые и регламентные задания
Фоновое задание, запущенное из сеанса, работает от имени того же пользователя — ИмяПользователя() вернёт его логин.
С регламентными заданиями иначе. Они выполняются от пользователя, который указан в настройках задания. Если поле пустое, задание работает без пользователя, и функция вернёт пустую строку. Учитывайте это, когда пишете в регламентном задании «автора» записи.
Кто сейчас в базе: активные сеансы и журнал регистрации
Узнать, под какими именами люди работают прямо сейчас, можно функцией ПолучитьСеансыИнформационнойБазы(). Она возвращает массив объектов СеансИнформационнойБазы, у каждого есть свойство Пользователь.
&НаСервереБезКонтекста
Функция СписокАктивныхСеансов()
Результат = Новый Массив;
Для Каждого Сеанс Из ПолучитьСеансыИнформационнойБазы() Цикл
Строка = СтрШаблон("№%1 %2, компьютер %3, приложение %4, начало %5",
Формат(Сеанс.НомерСеанса, "ЧГ=0"),
?(Сеанс.Пользователь = Неопределено, "<без пользователя>", Сеанс.Пользователь.Имя),
Сеанс.ИмяКомпьютера,
ПредставлениеПриложения(Сеанс.ИмяПриложения),
Формат(Сеанс.НачалоСеанса, "ДЛФ=DT"));
Результат.Добавить(Строка);
КонецЦикла;
Возврат Результат;
КонецФункции
В списке будут и служебные сеансы: фоновые задания, конфигуратор, внешние соединения. Отфильтровать их помогает ИмяПриложения: у тонкого клиента
это ThinClient, у веб-клиента — WebClient, у фонового задания — BackgroundJob.
Свой собственный сеанс вернёт ПолучитьТекущийСеансИнформационнойБазы(). Сравните НомерСеанса, если нужно исключить себя из списка.
Тот же массив помогает поймать «двойной вход». Посчитайте сеансы с одинаковым Пользователь.Имя и приложением ThinClient — если у логина их два и больше, под одной учётной записью работают с разных компьютеров. Это повод развести людей по отдельным пользователям: так журнал регистрации будет показывать, кто именно что сделал.
Без интерфейса: в типовых конфигурациях на БСП список работающих людей есть в разделе Администрирование, обработка «Активные пользователи». Там же можно завершить чужой сеанс — человек потеряет несохранённые данные, поэтому делайте это после предупреждения или вне рабочего времени.
Кто это сделал: имя пользователя из журнала регистрации
Сеансы показывают только настоящее. Для прошлого — кто провёл документ, кто входил вчера вечером — нужен журнал регистрации. Программно его выгружает ВыгрузитьЖурналРегистрации(); для этого нужно право администрирования.
&НаСервере
Процедура ВходыЗаСутки()
Таблица = Новый ТаблицаЗначений;
Отбор = Новый Структура;
Отбор.Вставить("ДатаНачала", НачалоДня(ТекущаяДатаСеанса()));
Отбор.Вставить("ДатаОкончания", КонецДня(ТекущаяДатаСеанса()));
Отбор.Вставить("Событие", "_$Session$_.Start");
ВыгрузитьЖурналРегистрации(Таблица, Отбор);
Для Каждого Запись Из Таблица Цикл
Сообщить(Формат(Запись.Дата, "ДЛФ=DT") + " " + Запись.ИмяПользователя
+ " " + Запись.Компьютер);
КонецЦикла;
КонецПроцедуры
_$Session$_.Start — служебный идентификатор события «Сеанс. Начало». Для изменения данных используйте _$Data$_.Update, для проведения — _$Data$_.Post.
Журнал за год в живой базе весит гигабайты. Всегда ставьте отбор по дате, иначе выгрузка займёт минуты и съест память рабочего процесса.
Как получить имя пользователя Windows и проверить вход через ОС
Здесь две разные задачи.
Задача 1. Какая учётная запись Windows привязана к пользователю 1С. Это свойство ПользовательОС объекта ПользовательИнформационнойБазы. Оно заполняется, когда в карточке пользователя включена аутентификация операционной системы.
&НаСервереБезКонтекста
Функция ПривязкаКWindows()
Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
Если Не Пользователь.АутентификацияОС Тогда
Возврат "Вход через Windows не настроен";
КонецЕсли;
Возврат Пользователь.ПользовательОС; // например, \\BUH\ivanova
КонецФункции
Задача 2. Под каким логином Windows реально сидит человек. Встроенной функции для этого нет. На клиенте под Windows выручает COM-объект WScript.Network:
&НаКлиенте
Функция ЛогинWindows()
#Если ВебКлиент Тогда
Возврат "";
#Иначе
Попытка
Сеть = Новый COMОбъект("WScript.Network");
Возврат Сеть.UserDomain + "\" + Сеть.UserName;
Исключение
Возврат "";
КонецПопытки;
#КонецЕсли
КонецФункции
Не вызывайте этот код на сервере. Там он вернёт учётную запись службы сервера 1С (например, USR1CV8), а не бухгалтера. В веб-клиенте и на Linux/macOS COM-объектов нет — отсюда условие и Попытка.
Аутентификация ОС, OpenID и веб-клиент
Когда вход настроен через Windows, пользователь не вводит пароль: платформа сама находит пользователя 1С по учётной записи. Для кода ничего не меняется — ИмяПользователя() всё равно вернёт логин 1С, а не Windows.
То же верно для OpenID-аутентификации и входа в опубликованную на веб-сервере базу. Функция возвращает пользователя информационной базы, сопоставленного с внешней учётной записью. Если сопоставления нет, вход не состоится.
Для HTTP- и веб-сервисов логика та же: код сервиса выполняется от пользователя 1С, указанного при авторизации запроса.
Типичные ошибки при получении имени пользователя
Ещё одна ловушка — логика прав на основе логина. Строки вроде Если ИмяПользователя() = "Администратор" ломаются при первой же смене состава сотрудников. Права в 1С решаются ролями, а проверка роли — одной функцией РольДоступна().