gifts2017

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

Опубликовал Александр Шевелев (shevelyov) в раздел Программирование - Работа с интерфейсом

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

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

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

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

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

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

 

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

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

 

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

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

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

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

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

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

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

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

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

 

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

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

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

 Результат

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

 

Upd:

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

 

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

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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Роман Озеряный (rozer) 29.10.15 10:20
есть только один недостаток ИМХО, выражение "НЕ В ИЕРАРХИИ" очень сильно нагружают СУБД
2. Александр Шевелев (shevelyov) 29.10.15 10:50
(1) rozer, согласен, мой отбор по оформлению происходит заметно долго даже на глаз, мне самому не очень нравится моё решение, но придумать что-либо проще не удалось. Может, кто поделится более удачным решением?
3. Евгений Самигулин (Paradise.87) 29.10.15 13:31
Топорный, но эффективный вариант: В реквизит группы или в РС записывать количество вложенных элементов (При записи номенклатуры или рег.заданием).
P.S. Но вроде и без реализации этой хотелки многие прекрасно живут.)
4. Анатолий Бритько (headMade) 29.10.15 14:23
shevelyov,
Главное отличие от того что есть в публикации http://infostart.ru/public/311136/ видно даже из постановки задачи: у вас "Когда требуется открыть список справочника с отбором, например,ПО ОПРЕДЕЛЕННО ГРУППЕ", а там "при открытии формы выбора накладываются определенные УСЛОВИЯ НА ЭЛЕМЕНТЫ СПРАВОЧНИКА". Т.е. вы сразу знаете какие группы д.б. видны, а там они определяется исходя из иерархии справочника и накладываемых условия отбора на элементы справочника.

Кроме того если вам надо показать огурцы, которые будут находиться в
-Группа "Овощи и фрукты"
-- Группа "Овощи"
--- Группа "Огурцы"
В вашем случаем пользователь будет видеть ТОЛЬКО группу "Огурцы", а там будет видна вся иерархиям полностью вплоть до группы "Огурцы".
shevelyov; +1 Ответить
5. shurik_shurik (shurik_shurik) 04.11.15 23:52
предложенный в этой статье вариант натолкнул меня на одну интересную мысль, решил проверить, вроде получилось:
        ГруппаКонструктора = Справочники.Номенклатура.НайтиПоКоду("00-00000001");
	
	ОтборПоГруппе = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборПоГруппе.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
	ОтборПоГруппе.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
	ОтборПоГруппе.ПравоеЗначение = ГруппаКонструктора;

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

Что интересно, без второй строки с "Отображать" система вела себя не адекватно..
А вообще смысл в том, что всем выключить видимость, а после по отбору "ВИерархии" включить....
Вот только не пойму, есть ли прирост в скорости по сравнению с "НЕ в ИЕРАРХИИ"
6. Александр Шевелев (shevelyov) 05.11.15 10:11
(5) shurik_shurik, Замерил производительность обоих вариантов. Ваш, если и быстрее, то на десятитысячную секунды. Зато понятнее и проще. Включил Ваш код в статью. Надеюсь, Вы не против? Да, оказалось, что отбор по группе (строки 2-5 Вашего кода) излишен!
7. Алексей Крайст (Chrizt) 05.11.15 11:51
А как быть с обычными формами?
8. shurik_shurik (shurik_shurik) 05.11.15 13:00
Вот Вам еще в копилку вариантов (правда он получается не совсем динамический, но эта проблема возникнет когда во время открытого списка, будут добавлять группы в корне справочнике или в группе выше от "ГруппаКонструктора"):
&НаСервере
Функция ПолучитьГруппыНеВИерархии(Группа)
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	Номенклатура.Ссылка
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	НЕ Номенклатура.Ссылка В ИЕРАРХИИ (&Группа)
	|	И Номенклатура.ЭтоГруппа";
	Запрос.УстановитьПараметр("Группа",Группа);
	Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
КонецФункции


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

Скорость можете замерить. Я у себя визуально увидел реальную разницу в работе списка.
Даже если групп будет очень много, проще их хранить в памяти сервера и проверять, чем каждый раз дергать базу запросом "В ИЕРАРХИИ", который, кстати, тоже не может похвастаться быстродействием...
Вот с отбором в первых строках, тут нужно проверять более детально, в моем случае разницы с ним и без не заметил, для компактности убрал.
UPD Можно еще доработать на контроль уровня, поскольку если будет отбор не по корневой папке, тогда весь "этот разговор" разбивается об стенку....
shevelyov; +1 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа