Где 1С хранит сведения о пользователе и как прочитать их из конфигурации
Содержание
Настройки текущего пользователя 1С получают на сервере: ПользователиИнформационнойБазы.ТекущийПользователь() возвращает объект с именем, ролями, языком и способами входа, а сохранённые значения пользователя читаются из ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек). На клиенте без вызова сервера доступны только ИмяПользователя() и ПолноеИмяПользователя().
Всё это механизмы платформы 1С:Предприятие 8.3, поэтому код одинаково работает в Бухгалтерии, ЗУП, УТ и самописных конфигурациях. Отличается только надстройка: в типовых решениях поверх платформы лежит БСП со своим справочником «Пользователи» и удобными обёртками.
Из чего складываются данные о пользователе в 1С
Слово «настройки» в 1С означает три разных слоя. Путаница между ними — главная причина, почему код «ничего не находит».
| Слой | Где живёт | Что там лежит | Чем читать |
|---|---|---|---|
| Пользователь информационной базы | Список пользователей платформы (Конфигуратор → Администрирование → Пользователи) | Имя, полное имя, роли, язык, основной интерфейс, режим запуска, аутентификация | ПользователиИнформационнойБазы |
| Элемент справочника «Пользователи» (БСП) | Обычный справочник конфигурации | Ссылка для документов, физлицо, подразделение, контактная информация | Пользователи.ТекущийПользователь() |
| Хранилища настроек | Служебные таблицы базы | Сохранённые отборы, варианты отчётов, положение форм, ваши произвольные значения | ХранилищеОбщихНастроек и другие |
Связь между первыми двумя слоями хранится в справочнике: у элемента «Пользователи» есть идентификатор пользователя ИБ. Поэтому «Иванов» в списке пользователей платформы и «Иванов» в справочнике — два разных объекта.
Хранилищ настроек у платформы несколько:
- 🗂
ХранилищеОбщихНастроек— произвольные значения по ключам, сюда пишет и разработчик, и БСП; - 🖥
ХранилищеСистемныхНастроек— то, что платформа сохраняет сама: размеры окон, состав панелей, история; - 📊
ХранилищеПользовательскихНастроекОтчетовиХранилищеВариантовОтчетов— отборы и варианты отчётов на СКД; - 📝
ХранилищеНастроекДанныхФорм— значения реквизитов форм, у которых включено сохранение.
Конфигурация может подменить любое из них своим хранилищем — это задаётся в свойствах корня конфигурации. Тогда методы Сохранить и Загрузить вызывают уже код этого хранилища.
Как получить данные текущего пользователя через код
Имя и полное имя — прямо на клиенте
Две функции глобального контекста работают везде, включая тонкий и веб-клиент:
Имя = ИмяПользователя(); // имя для входа, например "Иванов"
Представление = ПолноеИмяПользователя(); // "Иванов Петр Сергеевич"
Если в базе нет ни одного пользователя, обе функции вернут пустую строку. Это нормальная ситуация для файловой базы на компьютере разработчика, и код должен её переживать.
Роли, язык и режим запуска — на сервере
Полные сведения даёт объект ПользовательИнформационнойБазы. Тонкий клиент его не видит, поэтому пример разбит на клиентскую процедуру и серверную функцию, которая возвращает простые значения:
&НаКлиенте
Процедура ПоказатьДанныеПользователя(Команда)
Данные = ДанныеТекущегоПользователя();
Сообщить(СтрШаблон("Пользователь: %1 (%2), ролей: %3, язык: %4",
Данные.Имя, Данные.ПолноеИмя, Данные.Роли.Количество(), Данные.Язык));
КонецПроцедуры
&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
Результат = Новый Структура;
Результат.Вставить("Имя", ПользовательИБ.Имя);
Результат.Вставить("ПолноеИмя", ПользовательИБ.ПолноеИмя);
Результат.Вставить("Язык", ?(ПользовательИБ.Язык = Неопределено, "", ПользовательИБ.Язык.Имя));
Результат.Вставить("РежимЗапуска", Строка(ПользовательИБ.РежимЗапуска));
Результат.Вставить("ВходПоПаролю", ПользовательИБ.АутентификацияСтандартная);
Результат.Вставить("ВходЧерезWindows", ПользовательИБ.АутентификацияОС);
Роли = Новый Массив;
Для Каждого Роль Из ПользовательИБ.Роли Цикл
Роли.Добавить(Роль.Имя);
КонецЦикла;
Результат.Вставить("Роли", Роли);
Возврат Результат;
КонецФункции
Почему возвращается структура, а не сам объект: ПользовательИнформационнойБазы нельзя передать на клиент. Массив строк и примитивы передаются без проблем.
Для текущего пользователя ТекущийПользователь() не требует административных прав. А вот ПолучитьПользователей() и НайтиПоИмени() для чужих учётных записей уже требуют права «Администрирование».
Проверка роли и права без перебора
Перебирать роли ради одной проверки не нужно. Есть готовые функции:
Если РольДоступна("ПолныеПрава") Тогда
// показать служебные команды
КонецЕсли;
Если ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура) Тогда
// разрешить правку карточки
КонецЕсли;
РольДоступна проверяет конкретную роль, ПравоДоступа — итоговое право с учётом всех ролей. Второй вариант надёжнее: роли в типовых часто переименовывают и дробят при обновлении.
Параметры сеанса и окружения
К «настройкам текущего пользователя» часто относят и данные сеанса:
| Что нужно | Функция |
|---|---|
| Текущий язык интерфейса | ТекущийЯзык() |
| Обычное или управляемое приложение | ТекущийРежимЗапуска() |
Строка параметра /C из командной строки | ПараметрЗапуска (на клиенте) |
| Номер своего сеанса | НомерСеансаИнформационнойБазы() |
| Объект своего сеанса (компьютер, приложение, время начала) | ПолучитьТекущийСеансИнформационнойБазы() |
Ссылка на пользователя в типовой конфигурации
В конфигурациях на БСП для заполнения реквизита «Ответственный» нужна не учётная запись платформы, а ссылка на элемент справочника:
// на сервере
Ответственный = Пользователи.ТекущийПользователь();
Полноправный = Пользователи.ЭтоПолноправныйПользователь();
// на клиенте, без серверного вызова
Ответственный = ПользователиКлиент.ТекущийПользователь();
Если в базу может войти внешний пользователь (личный кабинет партнёра), Пользователи.ТекущийПользователь() для него вызовет исключение. Для такого кода берите Пользователи.АвторизованныйПользователь() — он вернёт ссылку либо на пользователя, либо на внешнего пользователя.
Чтение и запись произвольных настроек по ключам
Собственные значения пользователя — последний выбранный склад, флажки обработки, период по умолчанию — хранят в ХранилищеОбщихНастроек. Адрес значения состоит из двух строк:
- 🔑 КлючОбъекта — к чему относится настройка, обычно имя обработки или формы;
- 🔑 КлючНастроек — какая именно настройка внутри объекта.
Без параметра «ИмяПользователя» методы работают с настройками текущего пользователя.
Сохранение
&НаСервере
Процедура СохранитьНастройкиОбработки()
Настройки = Новый Структура;
Настройки.Вставить("Склад", Объект.Склад);
Настройки.Вставить("ТолькоОстатки", Объект.ТолькоОстатки);
ХранилищеОбщихНастроек.Сохранить("ОбработкаПереоценки", "Основные", Настройки);
КонецПроцедуры
Значение должно быть сериализуемым: примитивы, ссылки, структуры, массивы, таблицы значений подходят. Объект формы или ПользовательИнформационнойБазы сохранить не выйдет.
Загрузка с значением по умолчанию
&НаСервере
Процедура ЗагрузитьНастройкиОбработки()
Настройки = ХранилищеОбщихНастроек.Загрузить("ОбработкаПереоценки", "Основные");
Если ТипЗнч(Настройки) <> Тип("Структура") Тогда
Возврат; // настройки ещё не сохраняли — оставляем значения формы
КонецЕсли;
Если Настройки.Свойство("Склад") Тогда
Объект.Склад = Настройки.Склад;
КонецЕсли;
Если Настройки.Свойство("ТолькоОстатки") Тогда
Объект.ТолькоОстатки = Настройки.ТолькоОстатки;
КонецЕсли;
КонецПроцедуры
Загрузить возвращает Неопределено, если по ключу ничего нет. Проверка типа и Свойство() спасают от ошибки, когда в следующей версии обработки в структуре появится новое поле, а у пользователя лежит старый вариант.
Обёртки БСП
В типовых конфигурациях удобнее звать функции общего модуля — они сами подставляют значение по умолчанию и учитывают права:
// сервер
Склад = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"ОбработкаПереоценки", "Склад", Справочники.Склады.ПустаяСсылка());
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("ОбработкаПереоценки", "Склад", Склад);
// клиент
Склад = ОбщегоНазначенияВызовСервера.ХранилищеОбщихНастроекЗагрузить(
"ОбработкаПереоценки", "Склад", Неопределено);
Остальные операции
| Задача | Метод |
|---|---|
| Удалить одну настройку | ХранилищеОбщихНастроек.Удалить(КлючОбъекта, КлючНастроек, ИмяПользователя) |
| Получить список ключей объекта | ХранилищеОбщихНастроек.ПолучитьСписок(КлючОбъекта) |
| Прочитать настройку другого пользователя | Загрузить(КлючОбъекта, КлючНастроек, , ИмяПользователя) — нужны права администратора |
Придумайте единый префикс ключей для своих доработок, например МояФирма.ОбработкаПереоценки. Так ваши настройки не пересекутся с ключами БСП и легко найдутся при чистке.
Тонкий, толстый и веб-клиент: что где доступно
Чаще всего код «получения настроек» ломается при переносе из обычного приложения в управляемое. Сводка доступности:
| Механизм | Тонкий и веб-клиент | Толстый клиент | Сервер |
|---|---|---|---|
ИмяПользователя(), ПолноеИмяПользователя() | ✅ | ✅ | ✅ |
РольДоступна() | ✅ | ✅ | ✅ |
ПользователиИнформационнойБазы | ❌ | ✅ | ✅ |
ХранилищеОбщихНастроек и другие хранилища | ❌ | ✅ | ✅ |
ПользователиКлиент.ТекущийПользователь() (БСП) | ✅ | ✅ | — |
Отсюда практическое правило:
- Имя пользователя и проверку роли берите на клиенте, лишний вызов сервера не нужен.
- Объект пользователя ИБ и хранилища — только через функцию
&НаСервереили&НаСервереБезКонтекста. - В толстом клиенте код с
ПользователиИнформационнойБазыформально работает и без серверного вызова. Но если обработку потом откроют в тонком клиенте, она упадёт. Пишите сразу с разделением на клиент и сервер. - Не дёргайте сервер в цикле или в
ПриИзменениикаждого поля. Загрузите все настройки одним вызовом вПриСозданииНаСервере, а сохраните одним вызовом при закрытии.
Права доступа и безопасность
Работа с настройками опирается на несколько прав, и каждое ограничивает своё:
- 🔐 «Сохранение данных пользователя» — без него платформа не сохраняет пользовательские настройки: формы открываются в исходном виде, отборы не запоминаются;
- 🛡 «Администрирование» — нужно, чтобы получить список пользователей ИБ, найти чужую учётную запись или прочитать и записать чужие настройки;
- 🧑💼 права на справочник «Пользователи» — нужны, чтобы читать реквизиты элемента справочника, а не учётной записи платформы.
Что учесть при разработке:
Хранилище общих настроек не шифрует данные. Не сохраняйте в нём пароли, токены и ключи API. В БСП для секретов есть безопасное хранилище: ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище и ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища.
- Привилегированный режим (
УстановитьПривилегированныйРежим(Истина)) даёт коду все права. Включайте его в серверной процедуре на минимальный участок и выключайте сразу после чтения. - Не принимайте имя пользователя от клиента как доверенный параметр. Если серверная функция получает
ИмяПользователяиз формы и читает чужие настройки в привилегированном режиме, любой пользователь подставит чужое имя. - Решения о доступе принимайте на сервере. Проверка
РольДоступнана клиенте годится, чтобы спрятать кнопку, но не заменяет проверку в серверном коде.
Как посмотреть настройки пользователя без программирования
Иногда нужно просто проверить, что сохранено у сотрудника, без отладчика.
В Конфигураторе. Администрирование → Пользователи показывает учётные записи ИБ: на вкладках карточки видны роли, язык, основной интерфейс и способы аутентификации.
В типовой конфигурации на БСП. Раздел Администрирование → Настройки пользователей и прав содержит список пользователей и обработку «Настройки пользователей». В ней видно, какие настройки отчётов, внешнего вида и прочие сохранены у выбранного сотрудника. Там же их можно скопировать другому пользователю или очистить выборочно.
В режиме отладки. Поставьте точку останова после строки ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь(); и раскройте переменную в окне «Вычисление выражения» (Shift+F9). Видны все свойства объекта, включая Роли.
Сами настройки физически лежат в служебных таблицах базы (в клиент-серверном варианте — таблицы вида _CommonSettings, _SystemSettings, _RepSettings). Не правьте их напрямую через SQL — значения там сериализованы, и ручная правка ломает чтение настроек у пользователя.
Ошибки при получении настроек и как их отлаживать
ХранилищеОбщихНастроек.ПолучитьСписок(КлючОбъекта) и сравните ключи.Ещё несколько приёмов отладки:
- Проверьте, под кем идёт код. Фоновое задание и регламентное задание выполняются от имени пользователя, указанного в задании, а не того, кто сидит в базе.
ИмяПользователя()внутри них вернёт именно его. - Проверьте подмену хранилища. Если в свойствах конфигурации задано своё хранилище общих настроек, ошибка может быть в его модуле менеджера, а не в вашем коде.
- Сравните с чистым пользователем. Создайте тестовую учётную запись с теми же ролями. Если у неё всё работает — проблема в сохранённых данных конкретного сотрудника, их можно очистить через «Настройки пользователей».
Частые вопросы
Чем ИмяПользователя() отличается от Пользователи.ТекущийПользователь()?
ИмяПользователя() возвращает строку — имя учётной записи платформы. Пользователи.ТекущийПользователь() из БСП возвращает ссылку на элемент справочника «Пользователи», её записывают в реквизиты документов.Можно ли получить пароль текущего пользователя?
Пароль объекта пользователя ИБ доступно лишь для записи.Как получить настройки всех пользователей сразу?
ПользователиИнформационнойБазы.ПолучитьПользователей() и в цикле вызовите Загрузить с параметром ИмяПользователя. Нужны права администратора.Переживут ли сохранённые настройки обновление конфигурации?
Где хранятся настройки в файловой базе?
1Cv8.1CD, в тех же служебных таблицах, что и в клиент-серверной базе. Удаление кэша клиента с ключом /ClearCache их не затрагивает.