Фильтрация иерархического справочника по какому-либо условию в форме списка
Перед 1С программистами порой встаёт задача реализовать фильтрацию справочника по какому-нибудь условию прямо в форме списка (Например "ФормаСписка" или "ДляПодбора"). Вот и передо мной, недавно, поставили такую задачу. Она оказалась не такой уж и тривиальной, особенно для иерархического справочника…
- Описание
- Подробнее
Описание
Для решения данной задачи я решил воспользоваться методом формы списка «ИспользоватьСписокЭлементов(<СписокЗначений>)», так как использование процедуры «ОбработкаПодбора()» требует наличия реквизита справочника для отбора, а это мне не очень подходит. Порывшись в Интернете, на форумах я нашёл несколько реализаций алгоритмов фильтрации с использованием данного метода (например: «как перенести группы в справочниках в 1С 7.7 используя список значений, группы в справочние 1С и форма списка справочника», «v7: Функция ИспользоватьСписокЭлементов()», «Непонятные элементы с вопросительными знаками в многоуровневом справочнике при ИспользоватьСписокЭлементов»). Однако, IMHO, они имеют некоторые недостатки, вроде появления «левых» элементов справочника с «вопросиками», которые не должны отображаться при включении фильтра, переходе по иерархии справочника, установке/отключении режима вывода списка по группам, не позволяют нормально перемещаться по иерархии, либо слишком сложно реализованны…
Вот как я реализовал этот алгоритм (код из модуля формы списка справочника):
Функция СоответствуетУсловиямФильтра(ЭлементСправочника)
Если ПустоеЗначение(ЭлементСправочника) = 0 Тогда
//Условие фильтра: текущий остаток не равен нулю
Если Регистр.ПартииТоваров.СводныйОстаток(«»,ЭлементСправочника.ТекущийЭлемент(),,,,,«ОстатокТовара») <> 0 Тогда
Возврат 1;
КонецЕсли;
КонецЕсли;
Возврат 0;
КонецФункции
Процедура УстановитьФильтр(Знач Группа=«», Знач Иерархия=«»)
//Для флажка Фильтр задана формула «УстановитьФильтр()»
Если Фильтр = 1 Тогда
//Определяем параметры процедуры
Группа = ?(Группа=«»,ТекущийЭлемент().Родитель,Группа);
Иерархия = ?(Иерархия=«»,ИерархическийСписок(),Иерархия);
СписокФильтра = СоздатьОбъект(«СписокЗначений»);
Спр = СоздатьОбъект(«Справочник.Номенклатура»);
//Определяемся с использованием родителя при выборке элементов
Если ПустоеЗначение(Группа) = 0 Тогда
Спр.ИспользоватьРодителя(Группа);
КонецЕсли;
Спр.ВключатьПодчиненные(0);
//Выбираем элементы с учётом иерархии
Спр.ВыбратьЭлементы(Иерархия);
Пока Спр.ПолучитьЭлемент() = 1 Цикл
//Показваем группы, для удобства навигации
Если Спр.ЭтоГруппа() = 1 Тогда
//Добавляем группу в список фильтра
СписокФильтра.ДобавитьЗначение(Спр.ТекущийЭлемент());
Продолжить;
КонецЕсли;
//Проверяем элемент на соответствие условиям фильтра
Если СоответствуетУсловиямФильтра(Спр.ТекущийЭлемент()) = 1 Тогда
//Добавляем элемент в список фильтра
СписокФильтра.ДобавитьЗначение(Спр.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;
//Устанавливаем фильтр
ИспользоватьСписокЭлементов(СписокФильтра);
Иначе
//Снимаем фильтр
ИспользоватьСписокЭлементов();
КонецЕсли;
КонецПроцедуры
Процедура ПриВыбореРодителя(Элемент)
УстановитьФильтр(Элемент)
КонецПроцедуры
Процедура ПриСменеИерархии(Способ)
УстановитьФильтр(,Способ)
КонецПроцедуры
Функцией «СоответствуетУсловиямФильтра(ЭлементСправочника)» можно задавать любые условия фильтрации списка опираясь на передаваемый ей элемент справочника.
Скорость работы приемлема, но можно попробовать реализовать и через запрос…
Буду очень рад, если кому-нибудь пригодится 😉
P.S. Я в любом случае благодарю авторов алгоритмов и их собеседников из источников приведённых мной в ссылках.
