Как скрыть "пустые" группы справочника при открытии формы выбора? (только для УФ)

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

 Форма выбора ДО  Форма выбора ПОСЛЕ
 (видны «пустые» группы справочника, хотя выводятся только элементы с типом «Услуга»)  («пустых» групп справочника не видно)
 
Для того чтобы получить вышеуказанный указанный результат необходимо:
1. Определяем элементы справочника, которые необходимо показать пользователю.
2. При открытии формы выбора устанавливаем отбор по элементам из п.п.1
3. Определяем ГРУППЫ СПРАВОЧНИКА, которые НЕ ЯВЛЯЮТСЯ РОДИТЕЛЕМ для элементов из п.п.1
4. При открытии формы через условное оформление убираем видимость групп справочника из п.п. 3

Самым «толстым» моментов в этой схеме является п.п.3 «Определяем ГРУППЫ СПРАВОЧНИКА, которые НЕ ЯВЛЯЮТСЯ РОДИТЕЛЕМ«. Но для решения этой задачи был использован способ описанный ildarovich в статье Транзитивное замыкание запросом. После небольшой доработки ф-ии из этой статьи c легкостью можно получить группы справочника, которые не имеют никакого отношения к показываемым элементам справочника:

 
 
Функция ТранзитивноеЗамыкание(ИмяСправочника, МаксимальнаяДлинаПути, СписокИспользуемыхЭлементов) Экспорт
Пролог = "ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ Справочник.Номенклатура
| ГДЕ Родитель <> Значение(Справочник.Номенклатура.ПустаяСсылка)
| ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ Справочник.Номенклатура;";

Рефрен = "ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
| УНИЧТОЖИТЬ ЗамыканияДлины#1;";

Эпилог = "ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ИЗ ЗамыканияДлины#2 ГДЕ НачалоДуги <> КонецДуги";

Запрос = Новый Запрос(СтрЗаменить(Пролог, "Номенклатура", ИмяСправочника));

МаксимальнаяДлинаЗамыканий = 1;

Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл
Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0"));
МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий;
КонецЦикла;

/// НАЧАЛО ВНЕСЕННЫХ МНОЮ ИЗМЕНЕНИЙ В Ф-ИЮ        КУЛЬМИНАЦИЯ

//////Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0"));

Кульминация = "ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 ГДЕ НачалоДуги <> КонецДуги;
|УНИЧТОЖИТЬ ЗамыканияДлины#1;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    ЗамыканияДлины#2.Предок
|ПОМЕСТИТЬ СписокИспользуемыхГрупп
|ИЗ
|    ЗамыканияДлины#2 КАК ЗамыканияДлины#2
|ГДЕ
|    ЗамыканияДлины#2.Потомок В(&СписокИспользуемыхЭлементов)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    ЗамыканияДлины#2.Предок КАК Родитель
|ИЗ
|    ЗамыканияДлины#2 КАК ЗамыканияДлины#2
|        ЛЕВОЕ СОЕДИНЕНИЕ СписокИспользуемыхГрупп КАК СписокИспользуемыхГрупп
|        ПО ЗамыканияДлины#2.Предок = СписокИспользуемыхГрупп.Предок
|ГДЕ
|    СписокИспользуемыхГрупп.Предок ЕСТЬ NULL
|
|СГРУППИРОВАТЬ ПО
|    ЗамыканияДлины#2.Предок";


Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Кульминация, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(МаксимальнаяДлинаЗамыканий * 2, "ЧГ=0"));;
Запрос.УстановитьПараметр("СписокИспользуемыхЭлементов",СписокИспользуемыхЭлементов);

МассивНесипользуемыхГрупп = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Родитель");

СписокНеиспользуемыхГрупп = Новый СписокЗначений;
СписокНеиспользуемыхГрупп.ЗагрузитьЗначения(МассивНесипользуемыхГрупп);

Возврат СписокНеиспользуемыхГрупп;
КонецФункции
 Стоит отметить что приведенная функция работает достаточно шустро. Приведенная в статье функция не учитывает одну ситуацию — наличие в списке справочника ПУСТЫХ ГРУПП т.е. групп, у которых нет ни одного элемента. Но эту ситуацию легко обыграть, но при этом будет одно лишнее ображение к Справочнику для получения всех групп.
 
В статье находтся выгрузка базы, в которой на примере одного справочника показан принцип работы вышеописанного способа.
 
Дополнительная информация к ознакомлению:
4. Условное оформление в управляемых формах. (см. програмная работа с условным оформлением)
 

13 Comments

  1. shevelyov

    Предлагаю своё решение: http://infostart.ru/public/413242/ Мне кажется, оно проще.

    Reply
  2. headMade

    (1) shevelyov,

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

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

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

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

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

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

    Reply
  3. MECHTAKZ

    Очень классное решение.

    Reply
  4. scape

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

    Reply
  5. Ioanngood

    А есть подобное решение для обычных форм?

    Reply
  6. headMade

    (5) Для обычных форм ничего нет.

    Reply
  7. evgeniti

    Очень сложно. Зачем?

    Вся фишка заключается в том, что отбор компоновки дин списка и даже прямое условие дин списка в условии ГДЕ не справляется со скрытием ненужных групп.

    То есть такой код динамического списка не работает

    Выбрать
    Спр.Ссылка,
    Спр.ПолеОтбора
    из
    Справочник.НекийСправочник
    ГДЕ
    Спр.ПолеОтбора = «хочу оставить»
    

    Показать

    Чтобы скрыть группы надо перетащить условие фильтрации из ГДЕ в JOIN

    Выбрать
    Спр.Ссылка,
    Спр.ПолеОтбора
    из
    Справочник.НекийСправочник Спр
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ
    (Выбрать Фильтр.ссылка из Справочник.НекийСправочник как Фильтр где Фильтр.ПолеОтбора =  «хочу оставить») Фильтр
    По Спр.ссылка = Фильтр.Ссылка
    
    

    Показать

    Переданный в форму отбор достаточно превратить в параметры дин списка.

    Каменный цветок сразу получится.

    Reply
  8. headMade

    (7) ваше предложение это работающее решение или это концепция?

    У меня при использовании

    «ВНУТРЕННЕЕ СОЕДИНЕНИЕ… По Спр.ссылка = Фильтр.Ссылка «

    форма выбора в режиме просмотра «Дерево» ничего не показывает, а вот в режиме просмотра «Список» показывает ТОЛЬКО элементы (группы справочника не видны) по условию

    где Фильтр.ПолеОтбора =  «хочу оставить»

    Требуется еще какая-то доп настройка?

    Reply
  9. evgeniti

    (8) не концепция. вполне себе работает для верхнего уровня иерархии. Насчет старта с промежуточного — не было такой задачи 🙂

    По поводу только элементов — это решение для тех, кому не страшно разрешить реквизит фильтрации для группы, и далее заполнить его нужными данными. Иначе, как вы заметили, групп не будет видно. Тут, как говорится, «Вам шашечки или ехать».

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

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

    Вариант с видимостью я пробовал, но он себя забавно ведет иногда. Попробуйте нажать кнопку пометки удаления когда условным оформлением скрыты все элементы.

    А вообще, конечно, 1с подвела так подвела. Издевательство над людьми.

    Reply
  10. headMade

    (9) Спасибо за совет. Действительно при использовании

    «ВНУТРЕННЕЕ СОЕДИНЕНИЕ… По Спр.ссылка = Фильтр.Ссылка «

    можно «побороть» многие «особенности» поведения условного оформления (при использовании видимости).

    Reply
  11. alex-l19041

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

    Reply
  12. headMade

    (11) никаких. Просто кому что ближе по платформе. (и это не такси)

    Reply
  13. WiseSnake

    Нужно просто в динамическом списке > Настройки > Группировка выбрать группировку по «Родитель» и будет счастье

    Reply

Leave a Comment

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