Имя: Пароль:
1C
 
Как узнать принадлежность элемента к родителю самого верхного уровня?
0 чувак
 
13.09.06
14:03
Например такая иерархия:
ТОВАРЫ //1-уровень ГРУППА
     ПРОМТОВАРЫ //2-уровень ГРУППА
               ОДЕЖДА //3-уровень ГРУППА
                     Брюки // 4-уровень элемент
Как узнать что родитель самого верхного уровня элемента "Брюки" - это группа ТОВАРЫ?
1 PR
 
13.09.06
14:05
Небольшой цикл по поиску самого верхнего родителя.
2 чувак
 
13.09.06
14:05
(1) Как?
3 Zmich
 
13.09.06
14:08
Функция ОпределитьВерхнегоРодителя(ТекЭлем)
 Элем = ТекЭлем;
 Пока Элем.Уровень() <> 1 Цикл
   Элем = Элем.Родитель;
 КонецЦикла;
 Возврат Элем;
КонецФункции
4 Моха Лёхов
 
13.09.06
14:20
Я бы юзал полный код, выделил бы из него то, что до левого слеша и нашел бы элемент.
5 PR
 
13.09.06
14:22
(4) Была у меня и такая мысль, но не стал я ее писать, ибо неверная ;)
6 Моха Лёхов
 
13.09.06
14:38
(5) Почему?
Или запрос хитрый сделать можно попробовать.
ВЫБРАТЬ
*
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
&Товар В ИЕРАРХИИ(Номенклатура) И
Номенклатура.Родитель = &ПустаяНоменклатура

Это грубо, не проверял.
7 Моха Лёхов
 
13.09.06
14:38
Не прокатит запрос в (6)? А может его как-нить переделать можно?
8 megalodon
 
13.09.06
14:39
в (3) нормальный вариант. цикл или рекурсия.
9 Моха Лёхов
 
13.09.06
14:42
(8) семерошно :).
10 alexsy
 
13.09.06
14:43
полный код - тормозной вариант. рекурсией будет быстрее.
можно запрос отобрать по иерархии и по ней же отсортировать и взять первый. но что быстрее работать будет, запрос или рекурсия я не знаю.
11 Моха Лёхов
 
13.09.06
14:46
(10) про скорость не спорю. Не знаю. Но запрос - просто красиво :).
12 dimoff
 
13.09.06
14:46
По логике 6 быстрее должно работать чем 3
13 megalodon
 
13.09.06
14:47
самый быстрый по моему будет так:
ВЫБРАТЬ
Родитель.Родитель.Родитель.Родитель // и так далее ТекЭлем.Уровень() - 1
ИЗ
Справочник." + ТекЭлем.Метаданные().Имя + "
ГДЕ
Ссылка = &ТекЭлем";
14 alexsy
 
13.09.06
14:48
скорее всего все таки рекурсия быстрее. ну сколько там вложений может быть? 20? 20 раз вызвать функцию и прочитать один реквизит в ней - легко, а вот во всей выборке в иерархии может быть не одна тысяча записей...
15 dimoff
 
13.09.06
14:48
Ещё можно построить запрос
"Выбрать
Ссылка.Родитель.Родитель.Родитель
ИЗ Справочник.Номенклатура КАК Ном
ГДЕ Ном.Ссылка = &Элемент"

цепочка Родитель.Родитель.Родитель
составляется в зависимости от уровня элемента.
16 megalodon
 
13.09.06
14:48
(12) да никогда в жизни
17 alexsy
 
13.09.06
14:49
(13) дело! :)
осталось проверить что "уровень" работает не так медленно как "ПолныйКод"
:)
18 Алгоритм
 
13.09.06
14:51
Если Объект.ПринадлежитЭлементу(ЭлементСсылка) Тогда
   Сообщить("Принадлежит");
КонецЕсли;
19 Asmody
 
13.09.06
14:52
сделать запрос с итогами по иерархии, потом взять из этого запроса первый элемент...
20 alexsy
 
13.09.06
14:54
(19) если никуда не спешишь то можно и так :)
21 Моха Лёхов
 
13.09.06
14:56
(19) ИМХО, долго будет.
ОФФ: (15)(19) Мини ТЗ то вам дать по моей ветке, чтобы убедились? А то вы как-то там не появляетесь больше.
22 dimoff
 
13.09.06
14:57
(18) Очень в кассу
(17) Уровень скорей всего пишется непосредственно в таблицу, а не вычисляется по ссылкам, как полный код
23 ares
 
13.09.06
15:02
(6)Не работает твой чудо запрос, я в зврплате попробовал со справочником ФИзЛица и подразделенияОгранизации
24 Алгоритм
 
13.09.06
15:04
Ссылка = Справочники.Номенклатура.НайтиПоКоду("000000001");
   Пока НЕ Ссылка.Родитель.Ссылка.Пустая() Цикл
       Ссылка = Ссылка.Родитель;    
   КонецЦикла;
   Сообщить(Ссылка);
25 megalodon
 
13.09.06
15:05
хм, а уровень вообще забавно получается. вот есть у меня справочник, там нету ограничений количества уровней, но метод Уровень() для элемента 3-го уровня делает всего 1 запрос к БД (смотрит по 10-й уровень).
26 Моха Лёхов
 
13.09.06
15:05
(23) см. тогда (15). Если уж и он не работает ....
Я только идею дал, сам был не уверен в его работоспособности. Видать в скобках должен быть параметр, иначе нельзя сформировать таблицу.
27 ares
 
13.09.06
15:11
(26)По (15) сразу видно что он покажет только последнюю колонку,т.е. если .....Родитель.Родитель.Родитель (10 шт) а при данном элемента родитель заканчиваеться на 5, то выведен пустую строку или пожалуеться на ошибку
28 vde69
 
13.09.06
15:16
если надо найти для НЕСКОЛЬКИХ товаров то получить список ВСЕХ групп и в цикле проверять Товар.ПринадлежитЭлементу (Група) и Група.Уровень()=0
29 Asmody
 
13.09.06
15:17
(28) нафига список ВСЕХ групп? достаточно групп первого уровня...
30 vde69
 
13.09.06
15:19
(29) а как это в запросе сделать? поля уровень у справочника нет....
31 ares
 
13.09.06
15:33
Была задумка идти с конца

ЕСТЬNULL(ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель.Родитель, "А тут проверка след уровня т.е на уровень меньше, и так далее" )

Уровней не так уж много, у меня максимум 5 уровней, но эта тема почнему то не работает
32 FLENDGER
 
13.09.06
15:43
(9) - получается, что , так как в обычных языках программирования тоже используются цилы и рекурсии, то там тоже все по 7шному :)
лучше рабочее семерошное, чем неработающее восьморошное
(0) Кроме прделоженного цикла есть еще один метод:
    Получаешь полный код текущего элемента
    отрезаешь первую часть полного кода (которая до знака /) - это код элемента верхнего уровня
    находишь элементы через НайтиПоКоду по полному коду (подставив полученный выше код)
    перебираешь эти элементы и выбираешь тот, при котором ПервоначальныйЭлемент.ПринадлежитЭлементу(ОдинИзНайденныхЭлементов)
P.S. кода больше, но работать должно побыстрей перебора и рекурсии при больших справочниках с большим количеством вложений
33 Asmody
 
13.09.06
15:48
(30) ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка.Родитель=&ПустаяСсылка И Ссылка.ЭтоГруппа
34 Алгоритм
 
13.09.06
15:51
33 Получим все верхние группы, а де брюки
35 ares
 
13.09.06
15:54
Задумка была такой, пусть максимальный уровень иерархии будет 5, тогда
Для информации:
ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель.Родитель Как Родитель5,
ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель Как Родитель4,
ПодразделенияОрганизаций.Родитель.Родитель.Родитель Как Родитель3,
ПодразделенияОрганизаций.Родитель.Родитель Как Родитель2,
ПодразделенияОрганизаций.Родитель Как Родитель1,

А вот собственно и запрос :

ВЫБРАТЬ
   ПодразделенияОрганизаций.Ссылка,
   ЕСТЬNULL(Родитель5,ЕСТЬNULL(Родитель4,ЕСТЬNULL(Родитель3,ЕСТЬNULL(Родитель2, Родитель1)))) КАК Результат
ИЗ
   Справочник.ПодразделенияОрганизаций КАК ПодразделенияОрганизаций
ГДЕ
   ПодразделенияОрганизаций.Ссылка = &Ссылка

Только работает через раз т.е. чтобы проверить 5 уровень нужет 7
т.е. ЕСТЬNULL(Родитель7,ЕСТЬNULL(Родитель5,ЕСТЬNULL(Родитель3,Родитель1); Тогда работает, то теряеться через один.
36 Asmody
 
13.09.06
15:57
(35) Ёперный балет! что делать, если завтра в справочнике станет 256 уровней? (и не надо говорить, что я мудак, я это и сам знаю)
37 чувак
 
13.09.06
15:58
Получилось, кому интересно, код:
   Группа= Справочники.ФП_Справочники.НайтиПоНаименованию("Статьи оборотов");
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Ссылка
   |ИЗ
   |    Справочник.Номенклатура
   |ГДЕ
   |    Ссылка В ИЕРАРХИИ (&ВыбГруппа)
   |    И (НЕ Номенклатура.ЭтоГруппа)
   |    И ФП_Справочники.Ссылка = &Ссылка";
   Запрос.УстановитьПараметр("ВыбГруппа",Группа);
   Запрос.УстановитьПараметр("Ссылка",Ссылка);
   Результат=Запрос.Выполнить().Выбрать();
   Если  Результат.Количество()=1 тогда
       
   КонецЕсли;
38 ares
 
13.09.06
15:59
(36) это в каком справочнике может быть 256 уровней, ну 10, ну 20, ну 50 но не как ни 256
39 чувак
 
13.09.06
15:59
Сорри, те:
   Группа= Справочники.Номенклатура.НайтиПоНаименованию("Товары");
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Ссылка
   |ИЗ
   |    Справочник.Номенклатура
   |ГДЕ
   |    Ссылка В ИЕРАРХИИ (&ВыбГруппа)
   |    И (НЕ Номенклатура.ЭтоГруппа)
   |    И ФП_Справочники.Ссылка = &Ссылка";
   Запрос.УстановитьПараметр("ВыбГруппа",Группа);
   Запрос.УстановитьПараметр("Ссылка",Ссылка);
   Результат=Запрос.Выполнить().Выбрать();
   Если  Результат.Количество()=1 тогда
       
   КонецЕсли;
40 чувак
 
13.09.06
16:00
Опять мимо
   Группа= Справочники.ФП_Справочники.НайтиПоНаименованию("Статьи оборотов");
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Ссылка
   |ИЗ
   |    Справочник.Номенклатура
   |ГДЕ
   |    Ссылка В ИЕРАРХИИ (&ВыбГруппа)
   |    И (НЕ Ссылка.ЭтоГруппа)
   |    И Ссылка.Ссылка = &Ссылка";
   Запрос.УстановитьПараметр("ВыбГруппа",Группа);
   Запрос.УстановитьПараметр("Ссылка",Ссылка);
   Результат=Запрос.Выполнить().Выбрать();
   Если  Результат.Количество()=1 тогда
       
   КонецЕсли;
41 Алгоритм
 
13.09.06
16:00
39. Так ты ж сам указал родителя самого верхнего уровня :)
42 vde69
 
13.09.06
16:00
(33) согласен... можно наше совместное решение отдать Гению1С и в КЗ
43 Asmody
 
13.09.06
16:00
(37) и что ты тут проверил? как это у тебя проверяется принадлежность элемента одного справочника к группе другого справочника?
44 ares
 
13.09.06
16:01
(39)Это очень хорошо , но здесь спор идет как это все чисто в запросе написать и быстрее это будет чем програмно, а то что ты предложил будет дольше и перовго варианта и второго, ну насчет второго точно
45 Asmody
 
13.09.06
16:01
(38) сделать?
46 чувак
 
13.09.06
16:02
(43),(44) Извиняюсь я немножко пьян. Вот так наверно:

   Группа= Справочники.Номенклатура.НайтиПоНаименованию("Товары");
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Ссылка
   |ИЗ
   |    Справочник.Номенклатура
   |ГДЕ
   |    Ссылка В ИЕРАРХИИ (&ВыбГруппа)
   |    И (НЕ Ссылка.ЭтоГруппа)
   |    И Ссылка.Ссылка = &Ссылка";
   Запрос.УстановитьПараметр("ВыбГруппа",Группа);
   Запрос.УстановитьПараметр("Ссылка",Ссылка);
   Результат=Запрос.Выполнить().Выбрать();
   Если  Результат.Количество()=1 тогда
       
   КонецЕсли;
47 ares
 
13.09.06
16:02
(45) можно....,можно и в космос полететь, только кому это нужно, согласись?
48 PR
 
13.09.06
16:03
(6) Потому что уникальность кодов может быть отключена :))
49 чувак
 
13.09.06
16:05
(41) Вопрос как раз так и ставился: Принадлежить ли элемент к такой группе?
50 Asmody
 
13.09.06
16:06
(46) я правильно понимаю, что этот код заменяет метод ПринадлежитЭлементу() ?
51 чувак
 
13.09.06
16:07
(50) метод ПринадлежитЭлементу() указывает только родителя верхного уровня, а не самого верхного
52 PR
 
13.09.06
16:07
Мля, ну вы и развели бодягу с простого вопроса :o)
Вариантов два: рекурсия и запрос с условиями, независимый от количества уровней.
Оба озвучены.
Есть возможно и другие, но нах?
53 Asmody
 
13.09.06
16:07
(51) чего?!!!
54 ares
 
13.09.06
16:09
(52) Ну раз ты такой умный, предложи запрос с выводом верхнего родителя. При том что в звпросе нужно указать только элемент родителя которого мы и ищем.
55 чувак
 
13.09.06
16:11
(53) Хмм... да , не узнал что ест такой зверь.
Пасибо! Пойду продолжу пить
56 ares
 
13.09.06
16:11
Но то что развели из простого вопроса это что то, просто хочеться решить этот вопрос универсально(идеально). А просто решить я проблеем не вижу, немного запросов , немного кода и все готово. А охото запросом и только запросом
57 FLENDGER
 
13.09.06
16:29
(51) зря ты так думаешь :)
58 FLENDGER
 
13.09.06
16:33
да не получится в запросе для неограниченного количества уровней, так как в иерархии работает только в обратную сторону
59 PR
 
13.09.06
16:34
(54) Его уже озвучили, читай ветку
60 PR
 
13.09.06
16:35
(58) Все получится :))
61 Asmody
 
13.09.06
16:37
(60) ну ка, текст в студию! то что в (6) не сработает 100%
62 ares
 
13.09.06
17:22
(61) см. (23) я проверял ))
63 PR
 
13.09.06
17:49
(13), (19) например. Железные варианты, проверил :))
64 Neco
 
13.09.06
18:38
Как вариант:

ВЫБРАТЬ ПЕРВЫЕ 1
   Подразделения.Ссылка КАК Ссылка,
   Подразделения.Представление
ИЗ
   Справочник.Подразделения КАК Подразделения
ГДЕ
   Подразделения.Ссылка = &Ссылка
ИТОГИ ПО
   Ссылка ТОЛЬКО ИЕРАРХИЯ
65 PVasili
 
13.09.06
19:49
(36)больше 10 уровней в справочнике,imho, и даунов только может быть..
самый быстрый вариант через запрос типа родитель.родитель.родитель или родитель.родитель
Максимальный уровень(реальный а не из конфигуратора)можно запросом.На итланд был пример.При 100000 записей <1сек работал :)
66 PR
 
13.09.06
19:59
(64) Спорим, ты не проверял свой неработающий вариант?
67 PR
 
13.09.06
20:00
(65) Не, дауны - это те, кто не способен придумать такой пример :))
68 Neco
 
13.09.06
20:36
(66) Проверил на справочнике "Подразделения" в УПП в консоли отчетов  - выдает группировку последнего уровня
69 PR
 
13.09.06
21:30
(68) А, ну да, что-то я перепутал, ты же в запросе всю иерархию тянешь :o)
Некрасиво получается, всю иерархию тянешь, хотя нужен один элемент и неуниверсально, родитель уровня n уже так просто не вытянешь :O)
70 FLENDGER
 
14.09.06
10:26
(64) - норма!!! респект!!!
в принципе альтернатива другим алгоритмам...
(69) - ну вытянет он 10-20 элементов, из которых получит только первый? думаю не очень долго будет - порядка пару долей сек...
Зато что-то типа Родитель.Родитель.Родитель... и пр. :) - это конечно круто
может и элементы справочника будем перебирать руками (прям поэлементно, даже не используя Выбрать и пр.)?
Вытянет он родителя уровня N - это будет N-й оператор Следующий() для выборки