Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Запрос к справочнику: элемент и все его группы

Запрос к справочнику: элемент и все его группы
Я
   Asmody
 
22.04.19 - 12:34
Телезритель Asmody из Москвы задает вопрос знатокам:
Уважаемые знатоки! Допустим, у меня есть иерархический справочник (например, Номенклатура), с произвольным уровнем иерархии. Как мне запросом получить элементы справочника и все содержащие его группы?
Показываю на примере:


Группа1
|_Группа11
| |_Группа111
|   |_Элемент1
|_Группа12
  |_Элемент2



в результате:

Элемент1 | Группа1
Элемент1 | Группа11
Элемент1 | Группа111
Элемент2 | Группа1
Элемент2 | Группа12


 
 
   Cyberhawk
 
1 - 22.04.19 - 12:35
В 1С иерархия элементов и групп допускает только одного владельца
   Cyberhawk
 
2 - 22.04.19 - 12:35
("родителя")
   Asmody
 
3 - 22.04.19 - 12:36
На самом деле, вопрос "со звездочкой".
Мне нужны не все группы, а подходящие по определенному условию.
Но это можно решить отбором на результат запроса из (0)
   1Сергей
 
4 - 22.04.19 - 12:38
Можно наклепать там двадцать левых соединений, но потом хоп и попадутся элементы на 22 уровне и пипец
   fisher
 
5 - 22.04.19 - 12:40
Ответ "со звездочкой": http://catalog.mista.ru/public/158512/
Эффективно, если нужно по всему справочнику.
   Asmody
 
6 - 22.04.19 - 12:42
(5) Да, этот способ я знаю. Там текст запроса программно формируется. Меня это не совсем устраивает.
   Вафель
 
7 - 22.04.19 - 12:43
(6) тогда никак
   Вафель
 
8 - 22.04.19 - 12:44
ну или храни иерархию отдельно
   Nuobu
 
9 - 22.04.19 - 12:46
В ИЕРАРХИИ наоборот?
   Asmody
 
10 - 22.04.19 - 12:47
(9) Да. Если бы можно было использовать В ИЕРАРХИИ() в соединении таблиц.
   lodger
 
11 - 22.04.19 - 12:47
можно запрос и постобработку?
в конце запроса пишем
    |ИТОГИ ПО
    |    Родитель ИЕРАРХИЯ";

    РезультатЗапроса = Запрос.Выполнить();
    ОсновнаяВыборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    Пока ОсновнаяВыборка.Следующий() Цикл
// работаем с ОсновнаяВыборка.Родитель


        ВыборкаДетальныеЗаписи = ОсновнаяВыборка.Выбрать();
        
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// работаем с детзаписями

        КонецЦикла;
        
    КонецЦикла;
   fisher
 
12 - 22.04.19 - 12:48
(6) Программное формирование там только для оптимизации результирующего запроса под конкретный максимальный уровень вложенности. Фишка этого метода - в возможности покрытия очень большого уровня вложенности за небольшое количество шагов (нелинейная зависимость). То есть ты можешь просто написать готовый запрос с небольшим количеством этапов (не программно), который будет покрывать любую разумную глубину вложенности (сотню, скажем).
   xXeNoNx
 
13 - 22.04.19 - 12:50
>>Как мне запросом получить элементы справочника и все содержащие его группы?
... содержащие его - в смысле?

Иерархию можно записать в виде таблицы
ВЫБРАТЬ
Ссылка(представление),
Родитель(представление)
ЭтоГруппа
ИЗ
Справочник.Номенклатура
   xXeNoNx
 
14 - 22.04.19 - 12:54
Вопрос аналогичен групповым скидкам?
   1Сергей
 
15 - 22.04.19 - 12:56
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    НоменклатураРодитель.Ссылка КАК Родитель
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК НоменклатураРодитель
        ПО (Номенклатура.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
        ИЛИ (Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = НоменклатураРодитель.Ссылка)
ГДЕ
    НЕ НоменклатураРодитель.Ссылка ЕСТЬ NULL
   Asmody
 
16 - 22.04.19 - 13:02
Тогда попробую задачу сначала в упрощенном виде описать:
Мне нужно получить данные из регистра Продажи по номенклатуре. И эти данные должны быть свернуты по группам. Но не по всем группам в иерархии, а только по тем, которые имеют некоторый признак (для простоты считаем, что это булевый реквизит у группы НужнаяГруппа). "Нужные группы" не обязательно верхние. Кроме того, "нужные группы" могут быть вложены, но не подряд, а, например, через уровень.
Соответственно, образуется такая "псевдоиерархия".
Можно, конечно, запихнуть всё это в СКД, и постобработкой выводить только нужные строки, но это как-то неаккуратненько.
   fisher
 
17 - 22.04.19 - 13:07
(16) Напрашивается настройка формирования СКД по собственной иерархии, которую получать отдельным запросом. Но вычисление этой иерархии в запросе с "пропуском" уровней - это ИМХО будет уже удаление гландов ректально. Я бы попробовал подсунуть требуемую иерархию групп в СКД в качестве объекта ТЗ.
   fisher
 
18 - 22.04.19 - 13:08
Хотя, если подумать, то может и в запросе получится не так сложно, как мне сначала показалось.
   _Дайвер_
 
19 - 22.04.19 - 13:25
Получение всех родителей элемента
В языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться иерархическими итогами, однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями. Пример:

Пример:

ТекущийЭлементНоменклатуры = ЭлементНоменклатура;

Запрос = Новый Запрос("ВЫБРАТЬ 
                      | Номенклатура.Родитель, 
                      | Номенклатура.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель 
                      |ИЗ 
                      | Справочник.Номенклатура КАК Номенклатура 
                      |
                      |ГДЕ 
                      | Номенклатура.Ссылка = &ТекущийЭлементНоменклатуры"; 

Пока Истина Цикл 
    Запрос.УстановитьПараметр("ТекущийЭлементНоменклатуры", ТекущийЭлементНоменклатуры); 
    Результат = Запрос.Выполнить(); 
    Если Результат.Пустой() Тогда 
        Прервать; 
    КонецЕсли; 
    Выборка = Результат.Выбрать(); 
    Выборка.Следующий(); 
    Для НомерКолонки = 0 По Результат.Колонки.Количество() - 1 Цикл 
        ТекущийЭлементНоменклатуры = Выборка[НомерКолонки]; 
        Если ТекущийЭлементНоменклатуры = Справочники.Номенклатура.ПустаяСсылка() Тогда 
            Прервать; 
        Иначе 
            Сообщить(ТекущийЭлементНоменклатуры); 
        КонецЕсли; 
    КонецЦикла; 

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

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

Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.
   Ботаник Гарден Меран
 
20 - 22.04.19 - 13:29
Нормально запросом как в (5)
Количество уровней растет как степени двойки.
7 подзапросов и количество уровней 128 будет.
Есть такие маньяки, располагающие номенклатуру в сотом уровне вложенности?
   fisher
 
21 - 22.04.19 - 14:10
(20) Полная постановка задачи - в (16)
   Ботаник Гарден Меран
 
22 - 22.04.19 - 14:24
(21)
Это надо за ТС всё сделать?
Тогда ему сюда: https://forum.mista.ru/pro/index.php
   Сияющий в темноте
 
23 - 22.04.19 - 15:20
А если просто запрос элементов,а в итогах иерархия-он же сам ее построит,останется только выбрать и положить в таблицу.
   Сияющий в темноте
 
24 - 22.04.19 - 15:25
а по сути,выбираем в таблицу все элементы и группы и их непосредственные родители.
делаем индекс по элементам.
добавляем колонку номер строки с группой.

далее,из выборки необходимых элементов берем элемент и ищем его в созданной таблице,если номер строки группы задан,то переходим на нее и пишем группу,если нет,то или группа пустая и мы все нашли,или ищем в таблице группу и проставляем ей номер,чтобы в след.раз не искать,и так далее ...
   Asmody
 
25 - 22.04.19 - 15:29
Пока сделал через 5 раз ОБЪЕДИНИТЬ ВСЕ хвостом из Родитель.Родитель.Родитель...
   Жан Пердежон
 
26 - 22.04.19 - 15:39
(25) лучше б уж через доп.свойство/реквизит, в аналитических отчетах на иерархию опираться - в любом случае костыль будет
   Anarki
 
27 - 22.04.19 - 17:10
(16)Была задача один в один почти, и делал через транзитивное замыкание по статье из(5)


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.