Как скрыть "пустые группы" в списке выбора справочника при отборе




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

Стоит задача — открыть форму выбора справочника по определённой группе.

Вроде, всё просто, делаем отбор по иерархии:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ГруппаКонструктора = Параметры.ГруппаКонструктора;
ПроверочныйЭлемент = Параметры.ПроверочныйЭлемент;

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

 

В форме выбора в настройке списка видим требуемый отбор по группе «Огурцы»:

 отбор по иерархии

 

Однако сам список справочника выглядит неожиданно:

Список справочника только с отбором

Если открывать группы, видим, что элементы присутствуют только в группе «Огурцы», остальные группы пусты. Отбор работает, но от лишних «пустых» групп хотелось бы избавиться. 

Есть решение от headMade в этой публикации //infostart.ru/public/311136/ .

Я нашёл другой вариант условного оформления. Ниже вторая половина процедуры «ПриСозданииНаСервере» формы выбора справочника:

// установить видимость только в выбранной группе
ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);

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

Если ПроверочныйЭлемент.Пустая() Тогда
Элементы.Список.ТекущаяСтрока = ГруппаКонструктора;
Иначе
Элементы.Список.ТекущаяСтрока = ПроверочныйЭлемент;
КонецЕсли;

КонецПроцедуры

 

Данный код устанавливает параметр «Видимость» условного оформления динамического списка в значение «Нет» по следующему условию

Условие видимости групп справочника

Результат такого оформления ниже:

 Результат

Видна только нужная группа, её подгруппы и их элементы. Что, собственно, и хотелось увидеть.

 

Upd:

shurik_shurik предложил лучшее, более понятное решение (комментарий № 5):

 

    ГруппаКонструктора = Справочники.Номенклатура.НайтиПоКоду("00-00000001");

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

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

ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Истина );
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Отображать",Истина );

ОтборПоГруппе = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ОтборПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
ОтборПоГруппе.ПравоеЗначение = ГруппаКонструктора;
Кстати, удаление отбора по группе совершенно не изменяет работу кода! Получается, строки 2-5 лишние.

25 Comments

  1. rozer

    есть только один недостаток ИМХО, выражение «НЕ В ИЕРАРХИИ» очень сильно нагружают СУБД

    Reply ↓
  2. shevelyov

    (1) rozer, согласен, мой отбор по оформлению происходит заметно долго даже на глаз, мне самому не очень нравится моё решение, но придумать что-либо проще не удалось. Может, кто поделится более удачным решением?

    Reply ↓
  3. Paradise.87

    Топорный, но эффективный вариант: В реквизит группы или в РС записывать количество вложенных элементов (При записи номенклатуры или рег.заданием).

    P.S. Но вроде и без реализации этой хотелки многие прекрасно живут.)

    Reply ↓
  4. headMade

    shevelyov,

    Главное отличие от того что есть в публикации http://infostart.ru/public/311136/ видно даже из постановки задачи: у вас «Когда требуется открыть список справочника с отбором, например,ПО ОПРЕДЕЛЕННО ГРУППЕ», а там «при открытии формы выбора накладываются определенные УСЛОВИЯ НА ЭЛЕМЕНТЫ СПРАВОЧНИКА». Т.е. вы сразу знаете какие группы д.б. видны, а там они определяется исходя из иерархии справочника и накладываемых условия отбора на элементы справочника.

    Кроме того если вам надо показать огурцы, которые будут находиться в

    -Группа «Овощи и фрукты»

    — Группа «Овощи»

    — Группа «Огурцы»

    В вашем случаем пользователь будет видеть ТОЛЬКО группу «Огурцы», а там будет видна вся иерархиям полностью вплоть до группы «Огурцы».

    Reply ↓
  5. shurik_shurik

    предложенный в этой статье вариант натолкнул меня на одну интересную мысль, решил проверить, вроде получилось:

    ГруппаКонструктора = Справочники.Номенклатура.НайтиПоКоду(«00-00000001»);
    
    ОтборПоГруппе = Список.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
    ОтборПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(«Ссылка»);
    ОтборПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
    ОтборПоГруппе.ПравоеЗначение = ГруппаКонструктора;
    
    ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра(«Видимость», Ложь);
    
    ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра(«Видимость», Истина );
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра(«Отображать»,Истина );
    
    ОтборПоГруппе = ЭлементОформления.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
    ОтборПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(«Ссылка»);
    ОтборПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
    ОтборПоГруппе.ПравоеЗначение = ГруппаКонструктора;

    Показать

    Что интересно, без второй строки с «Отображать» система вела себя не адекватно..

    А вообще смысл в том, что всем выключить видимость, а после по отбору «ВИерархии» включить….

    Вот только не пойму, есть ли прирост в скорости по сравнению с «НЕ в ИЕРАРХИИ»

    Reply ↓
  6. shevelyov

    (5) shurik_shurik, Замерил производительность обоих вариантов. Ваш, если и быстрее, то на десятитысячную секунды. Зато понятнее и проще. Включил Ваш код в статью. Надеюсь, Вы не против? Да, оказалось, что отбор по группе (строки 2-5 Вашего кода) излишен!

    Reply ↓
  7. Chrizt

    А как быть с обычными формами?

    Reply ↓
  8. shurik_shurik

    Вот Вам еще в копилку вариантов (правда он получается не совсем динамический, но эта проблема возникнет когда во время открытого списка, будут добавлять группы в корне справочнике или в группе выше от «ГруппаКонструктора»):

    &НаСервере
    Функция ПолучитьГруппыНеВИерархии(Группа)
    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | Номенклатура.Ссылка
    |ИЗ
    | Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    | НЕ Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
    | И Номенклатура.ЭтоГруппа»;
    Запрос.УстановитьПараметр(«Группа»,Группа);
    Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(«Ссылка»);
    КонецФункции
    
    
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ГруппаКонструктора = Справочники.Номенклатура.НайтиПоКоду(«00-00000001»);
    
    ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра(«Видимость», Ложь);
    ОтборПоГруппе = ЭлементОформления.Отбор.Элементы.Добавить(Тип(«ЭлементОтбораКомпоновкиДанных»));
    ОтборПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(«Ссылка»);
    ОтборПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
    ОтборПоГруппе.ПравоеЗначение = ПолучитьГруппыНеВИерархии(ГруппаКонструктора);;
    КонецПроцедуры

    Показать

    Скорость можете замерить. Я у себя визуально увидел реальную разницу в работе списка.

    Даже если групп будет очень много, проще их хранить в памяти сервера и проверять, чем каждый раз дергать базу запросом «В ИЕРАРХИИ», который, кстати, тоже не может похвастаться быстродействием…

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

    UPD Можно еще доработать на контроль уровня, поскольку если будет отбор не по корневой папке, тогда весь «этот разговор» разбивается об стенку….

    Reply ↓
  9. scape

    В «такси» ведет себя не адекватно. Пропадает заголовок таблицы списка.

    Reply ↓
  10. unknown181538

    (0) У меня очень сильно тормозило.

    помогло следующее: т.к. элементы (не-группы) успешно скрываются отбором, то нужно в условия условного оформления добавить, условие, чтобы оно накладывалось только на группы.

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

    Показать

    Reply ↓
  11. AvalonE2008

    Большое спасибо за статью!

    Reply ↓
  12. user649060

    ИТС: Условное оформление формы

    «Не рекомендуется использовать условное оформление для скрытия в таблице строк целиком. Использование условного оформления для скрытия строк может негативно влиять на производительность и приводить к некорректному отображению содержимого таблицы.»

    Reply ↓
  13. shevelyov

    (12) Если есть лучшее и более простое решение — буду рад ознакомиться.

    Reply ↓
  14. user649060

    (13) «лучшего и более простого решения» отбора групп в динамическом списке не существует.

    Можно использовать РодительВерхнегоУровня таблицы формы.

    Можно отказаться от иерархического отображения вообще.

    Можно внутренними соединениями пошаманить.

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

    Reply ↓
  15. Nehc

    (6) «Да, оказалось, что отбор по группе (строки 2-5 Вашего кода) излишен!»

    Это только пока в справочнике элементов относительно не много!

    Попробовал на действительно большом справочнике — без предварительного отбора — так и не закончился вывод за разумное время.

    Так что да, не зря ИТС не рекомендует, но… Не понятно почему все-таки нет нормального способа скрыть группы.

    Reply ↓
  16. cruel

    Нашёл, как мне кажется «лучшее и более простое решение» вот тут: http://devtrainingforum.v8.1c.ru/forum/thread.jsp?id=560816

    Добавил в динамический список группировку по полю «Родитель». Всё сразу заработало.

    Reply ↓
  17. skyboy13

    А это разве дает иерархию? Они идут списком, но по родителю.

    Reply ↓
  18. shevelyov

    (17)

    Если в группе «Диагностика анемий» в результате отбора будет пусто, Вы её всё равно будете видеть. В чём и проблема.

    Reply ↓
  19. skyboy13

    Кстати нет, если пометить все позиции в группе на удаление, она исчезает !

    Так же если фильтр в выборке наложить. Группы — Гематологии нет (там все элементы помечены на удаление)

    Reply ↓
  20. skyboy13

    и кстати с деревом тоже получается

    Reply ↓
  21. skyboy13

    Но здесь другая проблема, это кол-во уровней. Оно постоянно. И если уровень вложенности ниже максимального, то папка верхнего уровня получается пустой. А в данном примере 4.

    То папка вложенности 2 в справочники, будет в данном варианте, как

    <Пусто> — <Пусто> — <Имя1>-<Имя2>

    Reply ↓
  22. Xershi

    (15) потому что отбор в режиме иерархии работает только на элементы. Сними режим в список и получишь что хотел.

    Reply ↓
  23. titlimilitryambia

    В примере настраивается видимость группы верхнего уровня. А я пробовала на вложенной группе. Попробовала все варианты из статьи — не видно группы. Оказалось чтобы она стала видна нужно чтобы моя группа была текущей. Если на ней спозиционироваться, то она видна. Если нет — настройка видимости конкретно ее при отключенной видимости остальных не помогает. Это если режим просмотра иерархический список

    Reply ↓
  24. Henistaromin

    (16)

    Добавил в динамический список группировку по полю «Родитель». Всё сразу заработало.

    Единственное, что мне помогло. Быстро и просто, без лишнего кода. Спасибо!

    Reply ↓
  25. user802036

    Спасибо огромное братан:) я 4 часа сидел, замучался блин, а твой код моментально подошёл)

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *