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