В практике программирования на платформе 1С:Предприятие мы часто сталкиваемся с необходимостью программного сохранения и чтения пользовательских настроек. Рассмотрим весьма распространенную ситуацию, когда разработчик пытается получить настройки конкретного пользователя, но система упорно возвращает Неопределено. Проанализируем, почему возникает такая ошибка и как правильно работать с объектом ХранилищеОбщихНастроек.
Допустим, мы пишем код для загрузки сохраненных настроек и используем следующий вызов:
Настройка = ХранилищеОбщихНастроек.Загрузить(
"КлючОбъекта",
"КлючНастроек",
,
ПользователиКлиентСервер.ТекущийПользователь()
);
В результате переменная Настройка получает значение Неопределено. Однако, если мы уберем четвертый параметр и вызовем метод для текущего сеанса, все отработает корректно. Выясним причину такого поведения.
Главная ошибка кроется в четвертом параметре метода Загрузить(). Разберем по шагам, что именно мы туда передаем. Функция ПользователиКлиентСервер.ТекущийПользователь() возвращает ссылку на элемент справочника "Пользователи".
Однако, согласно синтакс-помощнику платформы, методы ХранилищеОбщихНастроек.Загрузить() и Сохранить() ожидают в этом параметре строго тип Строка. Эта строка должна содержать имя пользователя Информационной Базы (логин), как оно задано в Конфигураторе, а не уникальный идентификатор (УИД) и не ссылку на справочник.
Когда мы передаем ссылку, платформа выполняет неявное преобразование типа к строке, то есть получает представление этой ссылки (обычно это наименование элемента справочника). Если наименование пользователя в справочнике хотя бы на один символ отличается от его логина в конфигураторе, платформа попытается найти настройки для несуществующего имени и вернет Неопределено.
Часто проблема проявляется не сразу, а после административных изменений. Рассмотрим ситуацию, когда системный администратор изменил логин пользователя или его наименование.
Чтобы избежать потерь настроек при переименовании, в конфигурациях, использующих Библиотеку стандартных подсистем (БСП), разработчикам рекомендуется использовать переопределяемые модули (например, ПользователиПереопределяемый.ПриЗаписиПользователяИнформационнойБазы), где можно программно перенести настройки со старого имени на новое.
Рассмотрим дополнительные факторы, которые могут влиять на результат метода Загрузить():
СохранениеДанныхПользователя. Без этого права механизмы хранилища настроек не будут работать корректно.АдминистрированиеДанных). Если код выполняется под обычным пользователем, попытка прочитать чужие настройки потерпит неудачу. Для обхода этого ограничения необходимо использовать привилегированный режим:
УстановитьПривилегированныйРежим(Истина);
Настройка = ХранилищеОбщихНастроек.Загрузить("КлючОбъекта", "КлючНастроек", , "ИмяПользователяИБ");
УстановитьПривилегированныйРежим(Ложь);
Если в нашей конфигурации внедрена БСП, настоятельно не рекомендуется использовать прямые методы платформы. Посмотрим на правильный подход с использованием оберток БСП:
// Вместо прямого обращения используем методы ОбщегоНазначения
Настройка = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"КлючОбъекта",
"КлючНастроек"
);
Почему это лучше? Проанализируем преимущества:
Иногда возможности хранилища используют нестандартно. Рассмотрим интересный прием: сохранение неких глобальных системных констант. Для этого настройки сохраняют под фиктивным именем пользователя, которого не существует в справочниках.
УстановитьПривилегированныйРежим(Истина);
ХранилищеОбщихНастроек.Сохранить(
"МояПодсистема_ГлобальныеНастройки",
"ПараметрыИнтеграции",
СтруктураНастроек,
,
"#ОбщиеНастройкиСистемы"
);
Поскольку логина "#ОбщиеНастройкиСистемы" в информационной базе нет, никто из реальных пользователей случайно не перезапишет эти данные при входе или выходе. Получать их программно можно также из-под привилегированного режима, жестко передавая эту строку в метод загрузки.
Подведем итог: При работе с ХранилищеОбщихНастроек всегда следите за типами данных. Передавайте только строковый логин пользователя из информационной базы, учитывайте наличие прав (или используйте привилегированный режим) и помните об отсутствии привязки настроек к уникальному идентификатору (УИДу) при переименовании пользователей.