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