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