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

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

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

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

Почему стандартный отбор не скрывает папки в обычном приложении

Выясним причину проблемы. В толстом клиенте обычного приложения при включенном режиме «Иерархический просмотр» объект СправочникСписок устроен так, что платформа принудительно выводит структуру папок верхнего уровня для обеспечения интерактивной навигации. При наложении отбора по реквизиту (например, Актуальность = Истина) ядро платформы автоматически добавляет неявное условие СправочникСписок.Отбор.ЭтоГруппа = Ложь. В результате фильтруются только элементы, а папки остаются видимыми, даже если реквизит актуальности добавлен для групп и заполнен.

Кроме того, в обработчиках ПриВыводеСтроки и ПриПолученииДанных табличного поля обычных форм объект ОформлениеСтроки не предоставляет свойства для полного скрытия узла дерева (в отличие от цвета, шрифта или видимости ячеек). Рассмотрим рабочие варианты обхода этого ограничения.

Способ 1. Ограничение доступа на уровне записей (RLS)

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

Разберем по шагам настройку ограничения:

  1. Добавим в справочник реквизит Актуальность (тип Булево), сделав его доступным и для элементов, и для групп.
  2. В роли пользователя (например, роль кассира) для объекта справочника перейдем на вкладку «Ограничение доступа к данным» для права «Чтение».
  3. Установим условие ограничения по реквизиту актуальности или по наименованию папки:

ГДЕ 
    Актуальность = ИСТИНА

Если требуется скрыть конкретную архивную группу и все ее содержимое, можно настроить проверку по родительской ветке:


ГДЕ 
    НЕ Наименование ПОДОБНО "Архив%"
    И НЕ Родитель.Наименование ПОДОБНО "Архив%"
    И НЕ Родитель.Родитель.Наименование ПОДОБНО "Архив%"

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

Способ 2. Замена СправочникСписок на табличное поле с типом ДеревоЗначений

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

Рассмотрим пример кода для формы списка:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Услуги.Ссылка КАК Ссылка,
    |   Услуги.Наименование КАК Наименование,
    |   Услуги.Код КАК Код,
    |   Услуги.ЭтоГруппа КАК ЭтоГруппа
    |ИЗ
    |   Справочник.Услуги КАК Услуги
    |ГДЕ
    |   (&ПоказыватьАрхив = ИСТИНА ИЛИ Услуги.Актуальность = ИСТИНА)
    |ИТОГИ ПО
    |   Ссылка ТОЛЬКО ИЕРАРХИЯ";

Запрос.УстановитьПараметр("ПоказыватьАрхив", ПоказыватьАрхив);

РезультатЗапроса = Запрос.Выполнить();
ДеревоДанных = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

ЭлементыФормы.ТабличноеПолеДерево.Значение = ДеревоДанных;
ЭлементыФормы.ТабличноеПолеДерево.СоздатьКолонки();

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

Способ 3. Условное оформление в управляемых формах (Динамический список)

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

Разберем настройку условного оформления динамического списка:

  1. Откроем свойства динамического списка в форме и перейдем в пункт «Настройки списка» -> «Условное оформление» (либо настроим его программно в событии ПриСозданииНаСервере).
  2. В колонке «Оформление» установим флаг Видимость = Ложь.
  3. В колонке «Условие» зададим отбор: Актуальность Равно Ложь (или Скрыто Равно Истина).
  4. В колонке «Оформляемые поля» оставляем список пустым, чтобы скрывалась вся строка целиком.

Посмотрим на программную установку условного оформления:


ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();

ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Актуальность");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементУсловия.ПравоеЗначение = Ложь;
ЭлементУсловия.Использование = Истина;

ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);

Данное условие отрабатывает корректно при любых режимах отображения: «Иерархический список», «Дерево» и «Список».

Способ 4. Отключение иерархического просмотра с отбором по списку

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Услуги.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Услуги КАК Услуги
    |ГДЕ
    |   Услуги.Актуальность = ИСТИНА";

СписокСсылок = Новый СписокЗначений;
СписокСсылок.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));

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

ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокСсылок;
ОтборСсылка.Использование = Истина;

Методологические рекомендации по хранению архивных услуг

Разберем архитектурную сторону вопроса. Регулярное создание архивных папок вроде «Услуги 2012» с последующей повторной загрузкой того же каталога приводит к дублированию элементов в базе данных, усложнению сопоставления в отчетах прошлых периодов и разрастанию таблиц ссылок.

Для правильного учета изменений прайс-листа рекомендуются следующие архитектурные подходы:

  1. Использование периодических регистров сведений: историчность цен и тарифов услуг фиксируется записями регистра сведений (например, ЦеныНоменклатуры) с периодичностью по дням. Сам элемент справочника остается неизменным, меняются только ценовые срезы на определенную дату.
  2. Регистр соответствия кодов: если внешняя организация периодически меняет внешние коды и названия позиций, в системе создается вспомогательный регистр соответствия (маппинга), который связывает внешние коды прайс-листа с постоянными внутренними ссылками справочника услуг без необходимости перемещать их в архивные папки.
← На главную