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