Как программно запретить разворачивание строки дерева в динамическом списке 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Рассмотрим ситуацию, с которой часто сталкиваются разработчики при настройке интерфейсов: необходимо ограничить доступ к определенной группе справочника (например, «Номенклатура») и запрашивать пароль при попытке пользователя открыть эту папку. Для этого динамический список переводится в режим отображения «Дерево», чтобы отлавливать клики по папкам. Разберем по шагам, как правильно реализовать этот механизм и почему очевидные подходы могут не сработать.

Почему метод Свернуть() не работает?

Часто программисты пытаются использовать событие ПриРазворачивании. Логика кажется прозрачной: пользователь кликает на плюсик, срабатывает событие, мы проверяем необходимость пароля и, если он не введен, вызываем метод Свернуть(), передавая в него текущую строку. Но на практике это не срабатывает.

Выясним причину. Метод Свернуть() предназначен для программного сворачивания уже развернутых узлов дерева. В момент срабатывания события ПриРазворачивании строка фактически еще находится в процессе изменения своего состояния платформой. Пытаться свернуть её в этот же самый момент — значит создать конфликт логики отрисовки формы на клиенте. Платформа просто проигнорирует команду.

Правильное решение: используем ПередРазворачиванием

Чтобы отменить действие пользователя по раскрытию группы, проанализируем доступные события элемента формы. Нам нужно событие, которое происходит до того, как платформа начинает отрисовывать дочерние элементы и делать ленивые запросы к базе данных. Этим событием является ПередРазворачиванием.

Посмотрим на пример кода. В обработчике этого события присутствует параметр Отказ. Установка этого параметра в значение Истина элегантно прерывает стандартную обработку платформы.


&НаКлиенте
Процедура СписокНоменклатураПередРазворачиванием(Элемент, Строка, Отказ)
    
    // Получаем данные текущей строки для проверки
    ТекущиеДанные = Элемент.ТекущиеДанные;
    
    Если ТекущиеДанные <> Неопределено И ТекущиеДанные.ТребуетсяПароль Тогда
        
        // Отменяем стандартное действие платформы по разворачиванию ветки
        Отказ = Истина;
        
        // Здесь можно вызвать собственную логику, например форму ввода пароля
        ЗапроситьПарольУПользователя(Строка);
        
    КонецЕсли;

КонецПроцедуры

Такой подход экономит ресурсы системы и не вызывает визуальных мерцаний интерфейса, так как строка остается в свернутом состоянии изначально.

Как закрыть лазейки в интерфейсе?

Если заказчик настаивает на таком механизме защиты (через пароль на папку), проанализируем ситуацию шире. Просто запретить разворачивать дерево недостаточно. Платформа 1С предоставляет пользователю множество штатных инструментов работы со списками. Разберем, какие настройки формы потребуется изменить, чтобы закрыть очевидные «дыры»:

  1. Запрет изменения режима просмотра: Если пользователь переключит режим просмотра с «Дерево» на «Список», то пароль запрашиваться не будет, и все элементы внутри папки станут видны общим списком. Необходимо отключить возможность смены режима в меню «Еще». Уберите галочки с команд переключения режима просмотра в свойствах формы.
  2. Ограничение настройки формы: Пользователь может зайти в «Все действия – Настроить список» и изменить отборы или группировки, тем самым полностью разрушив структуру дерева. Чтобы этого избежать, снимите флаг РазрешитьМенятьФорму у формы или отключите доступность команды настройки динамического списка.
  3. Блокировка глобального поиска: Если у списка включена строка поиска, пользователь легко найдет «закрытую» номенклатуру, просто введя часть её наименования. Для защиты установите свойства ПоложениеСтрокиПоиска и ПоложениеУправленияПоиском в значение «Нет».

Архитектурные проблемы решения и альтернативы

Рассмотрим подробнее, почему механизм установки пароля на интерфейсное событие не защищает данные глобально. Даже если вы идеально настроите форму списка справочника, данные останутся уязвимыми в других местах системы:

Если настройка RLS (Row Level Security) по каким-то причинам не подходит, рассмотрим программные способы скрытия без использования паролей:

Программный жесткий отбор: В событии ПриСозданииНаСервере динамическому списку программно добавляется отбор, исключающий секретную папку (например, Родитель <> ЗлополучнаяПапка). Этот отбор не выводится в быстрые пользовательские настройки, и пользователь просто не видит эту папку. Для доверенных лиц этот отбор программно снимается.

Ограничения использования в отборе: Существует метод УстановитьОграниченияИспользованияВОтборе(), который позволяет разработчику запретить пользователю фильтровать или искать данные по конкретным полям. Это гарантирует, что пользователь не сможет «обойти» наложенные программистом фильтры через расширенный поиск.

Тем не менее, в типовых конфигурациях настоятельно рекомендуется использовать встроенный механизм «Групп доступа». Достаточно привязать нужную папку к определенной группе доступа и указать эту группу в профиле пользователя. Это решает задачу на уровне ядра СУБД, надежно закрывая все бреши разом.

← На главную