При организации работы со справочниками номенклатуры или услуг часто возникает задача скрыть устаревшие позиции и целые архивные группы от глаз конечных пользователей (например, кассиров или операторов), сохранив при этом иерархическую структуру актуальных данных. Однако при попытке установить стандартный отбор в объекте СправочникСписок обычного приложения разработчики сталкиваются с техническим ограничением платформы: отборы применяются только к элементам, а группы продолжают отображаться в дереве каталога.
Проанализируем причины такого поведения платформы 1С:Предприятие и разберем практические способы решения этой задачи как для обычных, так и для управляемых форм.
Выясним причину проблемы. В толстом клиенте обычного приложения при включенном режиме «Иерархический просмотр» объект СправочникСписок устроен так, что платформа принудительно выводит структуру папок верхнего уровня для обеспечения интерактивной навигации. При наложении отбора по реквизиту (например, Актуальность = Истина) ядро платформы автоматически добавляет неявное условие СправочникСписок.Отбор.ЭтоГруппа = Ложь. В результате фильтруются только элементы, а папки остаются видимыми, даже если реквизит актуальности добавлен для групп и заполнен.
Кроме того, в обработчиках ПриВыводеСтроки и ПриПолученииДанных табличного поля обычных форм объект ОформлениеСтроки не предоставляет свойства для полного скрытия узла дерева (в отличие от цвета, шрифта или видимости ячеек). Рассмотрим рабочие варианты обхода этого ограничения.
Наиболее надежный и прозрачный способ для обычных форм — скрыть неактуальные папки на уровне механизма прав (RLS). Если пользователю запрещено чтение архивных групп, платформа физически не сможет отобразить их в дереве каталога.
Разберем по шагам настройку ограничения:
Актуальность (тип Булево), сделав его доступным и для элементов, и для групп.
ГДЕ
Актуальность = ИСТИНА
Если требуется скрыть конкретную архивную группу и все ее содержимое, можно настроить проверку по родительской ветке:
ГДЕ
НЕ Наименование ПОДОБНО "Архив%"
И НЕ Родитель.Наименование ПОДОБНО "Архив%"
И НЕ Родитель.Родитель.Наименование ПОДОБНО "Архив%"
При использовании RLS архивные папки полностью исчезают из дерева справочника при иерархическом просмотре, не ломая интерфейс и не требуя сложного программного кода в форме.
Если требуется интерактивно переключать видимость архива без изменения прав и без задержек RLS, мы можем отказаться от стандартного источника данных СправочникСписок и сформировать собственное иерархическое дерево через запрос.
Рассмотрим пример кода для формы списка:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Услуги.Ссылка КАК Ссылка,
| Услуги.Наименование КАК Наименование,
| Услуги.Код КАК Код,
| Услуги.ЭтоГруппа КАК ЭтоГруппа
|ИЗ
| Справочник.Услуги КАК Услуги
|ГДЕ
| (&ПоказыватьАрхив = ИСТИНА ИЛИ Услуги.Актуальность = ИСТИНА)
|ИТОГИ ПО
| Ссылка ТОЛЬКО ИЕРАРХИЯ";
Запрос.УстановитьПараметр("ПоказыватьАрхив", ПоказыватьАрхив);
РезультатЗапроса = Запрос.Выполнить();
ДеревоДанных = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ЭлементыФормы.ТабличноеПолеДерево.Значение = ДеревоДанных;
ЭлементыФормы.ТабличноеПолеДерево.СоздатьКолонки();
При таком подходе мы полностью контролируем состав отображаемых веток и элементов. Для сохранения пользовательского функционала достаточно назначить стандартные обработчики выбора строки и открытия формы элемента для созданного табличного поля.
Если конфигурация переводится на управляемые формы или в обычном приложении используется динамический список, скрыть группы становится намного проще. Механизм динамического списка поддерживает скрытие строк через условное оформление как для элементов, так и для групп в иерархическом режиме.
Разберем настройку условного оформления динамического списка:
ПриСозданииНаСервере).Видимость = Ложь.Актуальность Равно Ложь (или Скрыто Равно Истина).Посмотрим на программную установку условного оформления:
ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Актуальность");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементУсловия.ПравоеЗначение = Ложь;
ЭлементУсловия.Использование = Истина;
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
Данное условие отрабатывает корректно при любых режимах отображения: «Иерархический список», «Дерево» и «Список».
Если бизнес-процесс допускает отказ от древовидной структуры в пользу плоского списка, можно отключить иерархический просмотр и применить программный отбор по массиву ссылок, сформированному запросом:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Услуги.Ссылка КАК Ссылка
|ИЗ
| Справочник.Услуги КАК Услуги
|ГДЕ
| Услуги.Актуальность = ИСТИНА";
СписокСсылок = Новый СписокЗначений;
СписокСсылок.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"));
ЭлементыФормы.СправочникСписок.ИерархическийПросмотр = Ложь;
ЭлементыФормы.СправочникСписок.ПросмотрГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы;
ОтборСсылка = СправочникСписок.Отбор.Ссылка;
ОтборСсылка.ВидСравнения = ВидСравнения.ВСписке;
ОтборСсылка.Значение = СписокСсылок;
ОтборСсылка.Использование = Истина;
Разберем архитектурную сторону вопроса. Регулярное создание архивных папок вроде «Услуги 2012» с последующей повторной загрузкой того же каталога приводит к дублированию элементов в базе данных, усложнению сопоставления в отчетах прошлых периодов и разрастанию таблиц ссылок.
Для правильного учета изменений прайс-листа рекомендуются следующие архитектурные подходы:
ЦеныНоменклатуры) с периодичностью по дням. Сам элемент справочника остается неизменным, меняются только ценовые срезы на определенную дату.