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