Как скрыть группы (папки) в справочнике Номенклатура на обычных формах?

Программист 1С v8.3 (Обычные формы)
← На главную

При работе с обычными формами в 1С 8.2 или 8.3 разработчики часто сталкиваются с тем, что стандартные механизмы отбора в динамических списках ведут себя неочевидно при включенной иерархии. Типичная ситуация: мы устанавливаем фильтр по определенному реквизиту, элементы (товары) успешно скрываются, а группы (папки) продолжают отображаться, создавая визуальный шум или открывая доступ к пустой структуре каталогов. В этой статье мы подробно разберем, как заставить систему корректно скрывать папки, проанализируем различные события формы и рассмотрим альтернативные методы решения задачи.

Анализ проблемы: почему папки не скрываются?

Для начала выясним причину такого поведения системы. В обычных формах объект СправочникСписок (тип СправочникСписок.Номенклатура) при включенном режиме Иерархический просмотр старается сохранить структуру дерева. Если вы накладываете отбор на реквизит, который есть у элементов, но не заполнен или имеет другое значение у групп, система может отображать эти группы как "родительские контейнеры".

Рассмотрим ситуацию, описанную в теме: у справочника есть реквизит ВидимостьТашкент (тип Булево). Автор хочет видеть только те записи, где этот реквизит равен Истина. Проблема заключается в том, что даже если у элементов флаг стоит, а у папок — нет (или наоборот), отбор может отрабатывать не полностью. Давайте разберем по шагам, как это исправить.

Решение 1: Программная установка отбора по реквизиту группы

Первое, что необходимо сделать — убедиться, что реквизит, по которому идет фильтрация, заполнен и у самих групп. В 1С справочники могут иметь реквизиты, общие как для элементов, так и для групп. Если реквизит ВидимостьТашкент предназначен для управления доступом, он обязательно должен быть установлен в значение Истина у самой папки.

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


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

Важно помнить: если папка не соответствует условию отбора, она будет скрыта вместе со всеми вложенными элементами, даже если у элементов реквизит равен Истина. Это логика работы иерархических списков в 1С.

Решение 2: Использование события ПриПолученииДанных

Автор темы отметил, что перенос кода в событие ПриПолученииДанных помог решить проблему. Давайте разберем, почему это происходит и стоит ли так делать. Событие ПриПолученииДанных вызывается каждый раз, когда список отрисовывает строки на экране.

Внимание: Установка тяжелых отборов или запросов в этом событии может существенно замедлить работу интерфейса, особенно если в справочнике десятки тысяч записей. Однако, если стандартный отбор в ПриОткрытии "глючит" из-за специфики иерархии, можно принудительно обновлять состояние списка.

Посмотрим на пример реализации:


Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)
    // Устанавливаем отбор однократно или при необходимости обновления
    СправочникСписок.Отбор.ВидимостьТашкент.Установить(Истина);
КонецПроцедуры

Хотя автор нашел решение в этом событии, более профессиональным подходом считается использование ПриОткрытии или специализированных процедур обновления интерфейса, чтобы не перегружать цикл отрисовки строк.

Решение 3: Принудительное скрытие всех групп

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


// Скрываем все папки, оставляем только элементы
СправочникСписок.Отбор.ЭтоГруппа.ВидСравнения = ВидСравнения.Равно;
СправочникСписок.Отбор.ЭтоГруппа.Значение = Ложь;
СправочникСписок.Отбор.ЭтоГруппа.Использование = Истина;

Если же вы хотите программно отключить саму иерархию, чтобы список стал "плоским", используйте свойство элемента формы:

ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;

В плоском списке отборы по любым реквизитам работают максимально корректно, так как система перестает учитывать связи "родитель-ребенок" при визуализации строк.

Решение 4: Ограничение доступа на уровне записей (RLS)

Если ваша задача — не просто удобство интерфейса, а безопасность (например, "показывать папки только определенным ролям"), то использование отборов в форме — это плохая практика. Опытный пользователь сможет отключить отбор через настройки списка.

Рассмотрим более надежный метод — RLS (Record Level Security). Настроим ограничение в конфигураторе:

  1. Откроем роль пользователя.
  2. Найдем справочник Номенклатура.
  3. На праве Чтение нажмем "Ограничение доступа".
  4. Добавим условие на языке запросов:

ГДЕ ВидимостьТашкент = ИСТИНА

При использовании RLS система сама отсечет ненужные папки и элементы еще на уровне запроса к базе данных. Пользователь не увидит их ни в форме списка, ни в отчетах, ни при подборе. Это самое чистое решение с точки зрения архитектуры 1С.

Рекомендации по заполнению данных

Проанализируем ситуацию, когда код написан верно, но папки все равно видны. Проверьте следующие моменты:

Подводя итог, можно сказать: для скрытия папок в обычных формах наиболее эффективно сочетать правильную установку СправочникСписок.Отбор с предварительной проверкой данных в самих группах. Если же требуется жесткое разделение прав — используйте механизм RLS.

← На главную