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