Фильтрация иерархического справочника по какому-либо условию в форме списка

19.05.10

Разработка - Универсальные функции

Перед 1С программистами порой встаёт задача реализовать фильтрацию справочника по какому-нибудь условию прямо в форме списка (Например "ФормаСписка" или "ДляПодбора"). Вот и передо мной, недавно, поставили такую задачу. Она оказалась не такой уж и тривиальной, особенно для иерархического справочника...

Для решения данной задачи я решил воспользоваться методом формы списка "ИспользоватьСписокЭлементов(<СписокЗначений>)", так как использование процедуры "ОбработкаПодбора()" требует наличия реквизита справочника для отбора, а это мне не очень подходит. Порывшись в Интернете, на форумах я нашёл несколько реализаций алгоритмов фильтрации с использованием данного метода (например: "как перенести группы в справочниках в 1С 7.7 используя список значений, группы в справочние 1С и форма списка справочника", "v7: Функция ИспользоватьСписокЭлементов()", "Непонятные элементы с вопросительными знаками в многоуровневом справочнике при ИспользоватьСписокЭлементов"). Однако, IMHO, они имеют некоторые недостатки, вроде появления "левых" элементов справочника с "вопросиками", которые не должны отображаться при включении фильтра, переходе по иерархии справочника, установке/отключении режима вывода списка по группам, не позволяют нормально перемещаться по иерархии, либо слишком сложно реализованны...

Вот как я реализовал этот алгоритм (код из модуля формы списка справочника):

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

Процедура
УстановитьФильтр(Знач Группа="", Знач Иерархия="")
//Для флажка Фильтр задана формула "УстановитьФильтр()"
Если Фильтр = 1 Тогда
//Определяем параметры процедуры
Группа = ?(Группа="",ТекущийЭлемент().Родитель,Группа);
Иерархия = ?(Иерархия="",ИерархическийСписок(),Иерархия);
СписокФильтра = СоздатьОбъект("СписокЗначений");
Спр = СоздатьОбъект("Справочник.Номенклатура");
//Определяемся с использованием родителя при выборке элементов
Если ПустоеЗначение(Группа) = 0 Тогда
Спр.ИспользоватьРодителя(Группа);
КонецЕсли;

Спр.ВключатьПодчиненные(0);
//Выбираем элементы с учётом иерархии
Спр.ВыбратьЭлементы(Иерархия);
Пока Спр.ПолучитьЭлемент() = 1 Цикл
//Показваем группы, для удобства навигации
Если Спр.ЭтоГруппа() = 1 Тогда
//Добавляем группу в список фильтра
СписокФильтра.ДобавитьЗначение(Спр.ТекущийЭлемент());
Продолжить;
КонецЕсли;

//Проверяем элемент на соответствие условиям фильтра
Если СоответствуетУсловиямФильтра(Спр.ТекущийЭлемент()) = 1 Тогда
//Добавляем элемент в список фильтра
СписокФильтра.ДобавитьЗначение(Спр.ТекущийЭлемент());
КонецЕсли;
КонецЦикла;

//Устанавливаем фильтр
ИспользоватьСписокЭлементов(СписокФильтра);
Иначе

//Снимаем фильтр
ИспользоватьСписокЭлементов();
КонецЕсли;
КонецПроцедуры

Процедура
ПриВыбореРодителя(Элемент)
УстановитьФильтр(Элемент)
КонецПроцедуры


Процедура ПриСменеИерархии(Способ)
УстановитьФильтр(,Способ)
КонецПроцедуры

Функцией "СоответствуетУсловиямФильтра(ЭлементСправочника)" можно задавать любые условия фильтрации списка опираясь на передаваемый ей элемент справочника.

Скорость работы приемлема, но можно попробовать реализовать и через запрос...

Буду очень рад, если кому-нибудь пригодится ;)

P.S. Я в любом случае благодарю авторов алгоритмов и их собеседников из источников приведённых мной в ссылках.

См. также

Универсальные функции Программист Платформа 1С v7.7 Россия Абонемент ($m)

В библиотеку собраны различные функции по работе с документами, журналами, типами данных, строками, датой и временем, таблицами значений, Excel, файлами, XML, JSON, Http-сервисами, SMTP серверами и т.п.

1 стартмани

22.12.2023    1371    14    user706545_kseg1971    0    

5

Универсальные функции Программист Платформа 1С v7.7 Конфигурации 1cv7 Россия Бесплатно (free)

Получение реквизитов контрагентов из 1С:Контрагент для старых конфигураций под 1с 7.7.

25.04.2022    2339    zhenyat    7    

8

Универсальные функции Программист Платформа 1С v7.7 Россия Бесплатно (free)

Функция выводит таблицу значений в табличный документ. (v7.7) Особенно полезно при отладке. Не нужно вносить изменения в код, вызываем функцию как вычисляемое выражение при останове. Если таблица обрабатывается в несколько этапов, можно вывести её после каждого и визуально проследить эволюцию.

30.06.2021    5138    Zoltan_Black    11    

2

Универсальные функции Системный администратор Программист Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Установка принтера по умолчанию в 1С 7.7. Обработка может быть полезна в том случае, когда нужно установить принтер по умолчанию, а доступа к рабочему столу нет (например, терминальный режим без рабочего стола или remoteApp)

1 стартмани

13.02.2019    13933    4    alsen    3    

5

Универсальные функции Программист Платформа 1С v7.7 Конфигурации 1cv7 1С:Комплексная 7.7 Абонемент ($m)

Предлагается набор функций 1с 7.7 для формирования строки json стандартными средствами.

1 стартмани

10.12.2018    10766    malovandrey    7    

19

Универсальные функции Работа с интерфейсом Программист Платформа 1С v7.7 Конфигурации 1cv7 Россия Абонемент ($m)

В статье дано описание создания индикатора на форме в среде разработки 1С:Предприятие 7.7 исключительно типовыми средствами.

1 стартмани

27.09.2016    18887    2    HAMMER_59    6    

2
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Ёпрст 1065 20.05.10 09:27 Сейчас в теме
на большом справочнике это мегатормоз будет.
2. Antoska 17 20.05.10 09:50 Сейчас в теме
(1) Не спорю. Конечно может и будет тормозить на больших объёмах. Сам метод "ИспользоватьСписокЭлементов()" уже подразумевает небольшую скорость работы, я думаю. Проверял на справочнике "Номенклатура" в 2000 элементов. Захотелось поделиться с народом, поэтому и не притендую на то, что этот механизм необходимо использовать везде и всем. Однако, в сравнении с найденными мной решениями приведёнными по указанным ссылкам, этот вариан мне кажется наиболее приемлимым. Хотя задачи и условия всегда разные. На усмотрение программиста ;)
3. Noy 1079 20.05.10 09:51 Сейчас в теме
(1) Весьма достойно работает на справочнике в 20000 элементов, правда алгоритм чуть-чуть отличается
4. Antoska 17 20.05.10 10:03 Сейчас в теме
(3) Спасибо за испытания :)
5. Ёпрст 1065 20.05.10 10:11 Сейчас в теме
(3) "достойно", это как ? С задержкой в 5-10 секунд ?
6. Noy 1079 20.05.10 10:37 Сейчас в теме
(Antoska)
Испытаний не проводил - просто использую подобный подход
Пример: http://www.forum.mista.ru/topic.php?id=482087&all=1#60

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

ЗЫ посты видно в прямом эфире и на почту приходят, а на страничке обработки не отражаются... глюк?
8. Ёпрст 1065 20.05.10 11:09 Сейчас в теме
(6) Это не глюк, это баян..
:)
Пользуйся кнопкой "Очистить кеш публикации (beta)" вверху странички, справа...
10. Noy 1079 20.05.10 11:12 Сейчас в теме
(8) Гы... Спасибо.

(7) У меня статический список, который формируется в ПриНачалеРаботыСистемы. В посте просто "причесанный" пример.
12. Antoska 17 20.05.10 11:28 Сейчас в теме
(10) ПриНачалеРаботыСистемы? Ну, собсно, я уже и так увидел. Однако, не думаю, что это подходит для всех задач фильтрации. Как насчёт актуальности информации? Есть фозможность обновить список?
13. Noy 1079 20.05.10 11:34 Сейчас в теме
(12) фозможность :) есть - список в глобальной переменной. но в моем случае в этом нет необходимости. Этот же список используется во всех отчетах - то есть определенные пользователи видят в базе ограниченное количество клиентов/товаров и отчеты только по этим товарам/клиентам.

ЗЫ вообще не понимаю зачем фильтровать справочник по остаткам. Есть рабочий ассортимент и неактуальный - вот это еще можно фильтровать - но в этом случае или отбор или перенос в папку "яяНеактуальные товары" будет лучше. ИМХО
14. Antoska 17 20.05.10 11:39 Сейчас в теме
(13) Ну, насколько я успел поковыряться, для использования требуются ВК?

ЗЫ Зачем фильтровать? Прихоть товароведа :D Говорит так лучше! И это её ИМХО :)
15. Noy 1079 20.05.10 15:21 Сейчас в теме
(14) ВК нужно только для ускорения построения списка.

А как товаровед относится к тому, что при использовании данного фильтра поиск по первым буквам тормозит (особенно при отключенной иерархии)?
Товаровед все-таки активно работает в базе и быстрый поиск товара для нее очень важен.
16. Antoska 17 20.05.10 15:32 Сейчас в теме
(15) Не знаю как относится... Мне не жаловалась, значит устраивает, наверное :)
9. Ёпрст 1065 20.05.10 11:12 Сейчас в теме
(6) не.. имеется ввиду, насколько быстро работает сам метод "ИспользоватьСписокЭлементов", т.е его включение.

ЗЫ:... а автору нужно еше и список с останками создать.. а в (0) - вообще не быстро - перебор +сводныйостаток..
11. Antoska 17 20.05.10 11:22 Сейчас в теме
(9) А для чего, например, нужен список с останками? Мне, в данном конкретном случае, он не важен...
Функция "СоответствуетУсловиямФильтра()" приведена для примера (ну, это и так ясно ядумаю :) ), поэтому не важно что в ней. А насчёт перебора согласен - не самый быстрый способ, но я на нём и не настаиваю ;) . Просто привожу пример реализации... Кто захочит - переделает ;)
7. Antoska 17 20.05.10 10:58 Сейчас в теме
(Noy) Я такого варианта гуглом, к сожалению, не нашёл :| Правда для обновления фильтра, как я понял, необходимо переоткрывать справочник... Сейчас посмотрим :)

ЗЫ Такая же проблема с постами. Наверное, действительно, глюки на сайте :(
17. homichochik 24.09.10 20:25 Сейчас в теме
18. Antoska 17 27.09.10 10:27 Сейчас в теме
(17) Пожалуйста! Для того и выкладывал ;)
19. пользователь 16.02.12 11:33
Сообщение было скрыто модератором.
...
Оставьте свое сообщение