Где 1С хранит сведения о пользователе и как прочитать их из конфигурации

· 9 мин

Содержание

Настройки текущего пользователя 1С получают на сервере: ПользователиИнформационнойБазы.ТекущийПользователь() возвращает объект с именем, ролями, языком и способами входа, а сохранённые значения пользователя читаются из ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастроек). На клиенте без вызова сервера доступны только ИмяПользователя() и ПолноеИмяПользователя().

Всё это механизмы платформы 1С:Предприятие 8.3, поэтому код одинаково работает в Бухгалтерии, ЗУП, УТ и самописных конфигурациях. Отличается только надстройка: в типовых решениях поверх платформы лежит БСП со своим справочником «Пользователи» и удобными обёртками.

Из чего складываются данные о пользователе в 1С

Слово «настройки» в 1С означает три разных слоя. Путаница между ними — главная причина, почему код «ничего не находит».

СлойГде живётЧто там лежитЧем читать
Пользователь информационной базыСписок пользователей платформы (Конфигуратор → Администрирование → Пользователи)Имя, полное имя, роли, язык, основной интерфейс, режим запуска, аутентификацияПользователиИнформационнойБазы
Элемент справочника «Пользователи» (БСП)Обычный справочник конфигурацииСсылка для документов, физлицо, подразделение, контактная информацияПользователи.ТекущийПользователь()
Хранилища настроекСлужебные таблицы базыСохранённые отборы, варианты отчётов, положение форм, ваши произвольные значенияХранилищеОбщихНастроек и другие

Связь между первыми двумя слоями хранится в справочнике: у элемента «Пользователи» есть идентификатор пользователя ИБ. Поэтому «Иванов» в списке пользователей платформы и «Иванов» в справочнике — два разных объекта.

Хранилищ настроек у платформы несколько:

  • 🗂 ХранилищеОбщихНастроек — произвольные значения по ключам, сюда пишет и разработчик, и БСП;
  • 🖥 ХранилищеСистемныхНастроек — то, что платформа сохраняет сама: размеры окон, состав панелей, история;
  • 📊 ХранилищеПользовательскихНастроекОтчетов и ХранилищеВариантовОтчетов — отборы и варианты отчётов на СКД;
  • 📝 ХранилищеНастроекДанныхФорм — значения реквизитов форм, у которых включено сохранение.

Конфигурация может подменить любое из них своим хранилищем — это задаётся в свойствах корня конфигурации. Тогда методы Сохранить и Загрузить вызывают уже код этого хранилища.

Как получить данные текущего пользователя через код

Имя и полное имя — прямо на клиенте

Две функции глобального контекста работают везде, включая тонкий и веб-клиент:

Имя = ИмяПользователя();            // имя для входа, например "Иванов"
Представление = ПолноеИмяПользователя(); // "Иванов Петр Сергеевич"

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

Роли, язык и режим запуска — на сервере

Полные сведения даёт объект ПользовательИнформационнойБазы. Тонкий клиент его не видит, поэтому пример разбит на клиентскую процедуру и серверную функцию, которая возвращает простые значения:

&НаКлиенте
Процедура ПоказатьДанныеПользователя(Команда)
    Данные = ДанныеТекущегоПользователя();
    Сообщить(СтрШаблон("Пользователь: %1 (%2), ролей: %3, язык: %4",
        Данные.Имя, Данные.ПолноеИмя, Данные.Роли.Количество(), Данные.Язык));
КонецПроцедуры

&НаСервереБезКонтекста
Функция ДанныеТекущегоПользователя()

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

    Результат = Новый Структура;
    Результат.Вставить("Имя", ПользовательИБ.Имя);
    Результат.Вставить("ПолноеИмя", ПользовательИБ.ПолноеИмя);
    Результат.Вставить("Язык", ?(ПользовательИБ.Язык = Неопределено, "", ПользовательИБ.Язык.Имя));
    Результат.Вставить("РежимЗапуска", Строка(ПользовательИБ.РежимЗапуска));
    Результат.Вставить("ВходПоПаролю", ПользовательИБ.АутентификацияСтандартная);
    Результат.Вставить("ВходЧерезWindows", ПользовательИБ.АутентификацияОС);

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

    Возврат Результат;

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

Почему возвращается структура, а не сам объект: ПользовательИнформационнойБазы нельзя передать на клиент. Массив строк и примитивы передаются без проблем.

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

Проверка роли и права без перебора

Перебирать роли ради одной проверки не нужно. Есть готовые функции:

Если РольДоступна("ПолныеПрава") Тогда
    // показать служебные команды
КонецЕсли;

Если ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура) Тогда
    // разрешить правку карточки
КонецЕсли;

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

Параметры сеанса и окружения

К «настройкам текущего пользователя» часто относят и данные сеанса:

Что нужноФункция
Текущий язык интерфейсаТекущийЯзык()
Обычное или управляемое приложениеТекущийРежимЗапуска()
Строка параметра /C из командной строкиПараметрЗапуска (на клиенте)
Номер своего сеансаНомерСеансаИнформационнойБазы()
Объект своего сеанса (компьютер, приложение, время начала)ПолучитьТекущийСеансИнформационнойБазы()

Ссылка на пользователя в типовой конфигурации

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

// на сервере
Ответственный = Пользователи.ТекущийПользователь();
Полноправный = Пользователи.ЭтоПолноправныйПользователь();

// на клиенте, без серверного вызова
Ответственный = ПользователиКлиент.ТекущийПользователь();

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

Чтение и запись произвольных настроек по ключам

Собственные значения пользователя — последний выбранный склад, флажки обработки, период по умолчанию — хранят в ХранилищеОбщихНастроек. Адрес значения состоит из двух строк:

  • 🔑 КлючОбъекта — к чему относится настройка, обычно имя обработки или формы;
  • 🔑 КлючНастроек — какая именно настройка внутри объекта.

Без параметра «ИмяПользователя» методы работают с настройками текущего пользователя.

Сохранение

&НаСервере
Процедура СохранитьНастройкиОбработки()
    Настройки = Новый Структура;
    Настройки.Вставить("Склад", Объект.Склад);
    Настройки.Вставить("ТолькоОстатки", Объект.ТолькоОстатки);
    ХранилищеОбщихНастроек.Сохранить("ОбработкаПереоценки", "Основные", Настройки);
КонецПроцедуры

Значение должно быть сериализуемым: примитивы, ссылки, структуры, массивы, таблицы значений подходят. Объект формы или ПользовательИнформационнойБазы сохранить не выйдет.

Загрузка с значением по умолчанию

&НаСервере
Процедура ЗагрузитьНастройкиОбработки()
    Настройки = ХранилищеОбщихНастроек.Загрузить("ОбработкаПереоценки", "Основные");
    Если ТипЗнч(Настройки) <> Тип("Структура") Тогда
        Возврат; // настройки ещё не сохраняли — оставляем значения формы
    КонецЕсли;
    Если Настройки.Свойство("Склад") Тогда
        Объект.Склад = Настройки.Склад;
    КонецЕсли;
    Если Настройки.Свойство("ТолькоОстатки") Тогда
        Объект.ТолькоОстатки = Настройки.ТолькоОстатки;
    КонецЕсли;
КонецПроцедуры

Загрузить возвращает Неопределено, если по ключу ничего нет. Проверка типа и Свойство() спасают от ошибки, когда в следующей версии обработки в структуре появится новое поле, а у пользователя лежит старый вариант.

Обёртки БСП

В типовых конфигурациях удобнее звать функции общего модуля — они сами подставляют значение по умолчанию и учитывают права:

// сервер
Склад = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
    "ОбработкаПереоценки", "Склад", Справочники.Склады.ПустаяСсылка());
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("ОбработкаПереоценки", "Склад", Склад);

// клиент
Склад = ОбщегоНазначенияВызовСервера.ХранилищеОбщихНастроекЗагрузить(
    "ОбработкаПереоценки", "Склад", Неопределено);

Остальные операции

ЗадачаМетод
Удалить одну настройкуХранилищеОбщихНастроек.Удалить(КлючОбъекта, КлючНастроек, ИмяПользователя)
Получить список ключей объектаХранилищеОбщихНастроек.ПолучитьСписок(КлючОбъекта)
Прочитать настройку другого пользователяЗагрузить(КлючОбъекта, КлючНастроек, , ИмяПользователя) — нужны права администратора

Придумайте единый префикс ключей для своих доработок, например МояФирма.ОбработкаПереоценки. Так ваши настройки не пересекутся с ключами БСП и легко найдутся при чистке.

Тонкий, толстый и веб-клиент: что где доступно

Чаще всего код «получения настроек» ломается при переносе из обычного приложения в управляемое. Сводка доступности:

МеханизмТонкий и веб-клиентТолстый клиентСервер
ИмяПользователя(), ПолноеИмяПользователя()✅✅✅
РольДоступна()✅✅✅
ПользователиИнформационнойБазы❌✅✅
ХранилищеОбщихНастроек и другие хранилища❌✅✅
ПользователиКлиент.ТекущийПользователь() (БСП)✅✅—

Отсюда практическое правило:

  1. Имя пользователя и проверку роли берите на клиенте, лишний вызов сервера не нужен.
  2. Объект пользователя ИБ и хранилища — только через функцию &НаСервере или &НаСервереБезКонтекста.
  3. В толстом клиенте код с ПользователиИнформационнойБазы формально работает и без серверного вызова. Но если обработку потом откроют в тонком клиенте, она упадёт. Пишите сразу с разделением на клиент и сервер.
  4. Не дёргайте сервер в цикле или в ПриИзменении каждого поля. Загрузите все настройки одним вызовом в ПриСозданииНаСервере, а сохраните одним вызовом при закрытии.

Права доступа и безопасность

Работа с настройками опирается на несколько прав, и каждое ограничивает своё:

  • 🔐 «Сохранение данных пользователя» — без него платформа не сохраняет пользовательские настройки: формы открываются в исходном виде, отборы не запоминаются;
  • 🛡 «Администрирование» — нужно, чтобы получить список пользователей ИБ, найти чужую учётную запись или прочитать и записать чужие настройки;
  • 🧑‍💼 права на справочник «Пользователи» — нужны, чтобы читать реквизиты элемента справочника, а не учётной записи платформы.

Что учесть при разработке:

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

  • Привилегированный режим (УстановитьПривилегированныйРежим(Истина)) даёт коду все права. Включайте его в серверной процедуре на минимальный участок и выключайте сразу после чтения.
  • Не принимайте имя пользователя от клиента как доверенный параметр. Если серверная функция получает ИмяПользователя из формы и читает чужие настройки в привилегированном режиме, любой пользователь подставит чужое имя.
  • Решения о доступе принимайте на сервере. Проверка РольДоступна на клиенте годится, чтобы спрятать кнопку, но не заменяет проверку в серверном коде.

Как посмотреть настройки пользователя без программирования

Иногда нужно просто проверить, что сохранено у сотрудника, без отладчика.

В Конфигураторе. Администрирование → Пользователи показывает учётные записи ИБ: на вкладках карточки видны роли, язык, основной интерфейс и способы аутентификации.

В типовой конфигурации на БСП. Раздел Администрирование → Настройки пользователей и прав содержит список пользователей и обработку «Настройки пользователей». В ней видно, какие настройки отчётов, внешнего вида и прочие сохранены у выбранного сотрудника. Там же их можно скопировать другому пользователю или очистить выборочно.

В режиме отладки. Поставьте точку останова после строки ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь(); и раскройте переменную в окне «Вычисление выражения» (Shift+F9). Видны все свойства объекта, включая Роли.

Сами настройки физически лежат в служебных таблицах базы (в клиент-серверном варианте — таблицы вида _CommonSettings, _SystemSettings, _RepSettings). Не правьте их напрямую через SQL — значения там сериализованы, и ручная правка ломает чтение настроек у пользователя.

Ошибки при получении настроек и как их отлаживать

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

Ещё несколько приёмов отладки:

  1. Проверьте, под кем идёт код. Фоновое задание и регламентное задание выполняются от имени пользователя, указанного в задании, а не того, кто сидит в базе. ИмяПользователя() внутри них вернёт именно его.
  2. Проверьте подмену хранилища. Если в свойствах конфигурации задано своё хранилище общих настроек, ошибка может быть в его модуле менеджера, а не в вашем коде.
  3. Сравните с чистым пользователем. Создайте тестовую учётную запись с теми же ролями. Если у неё всё работает — проблема в сохранённых данных конкретного сотрудника, их можно очистить через «Настройки пользователей».

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

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