Как определить родителя верхнего уровня 1с запрос?

17 ответов на вопрос “Как определить родителя верхнего уровня 1с запрос?”

  1. WYWAJIG Ответить

    RomaH
    11.11.12 – 11:13
    Иерархия групп и элементов
    есть элемент справочника, при печати надо напечатать наименование группы первого уровня в которую входит этот элемент
    как получить группу первого уровня?

    golden-pack
    1 – 11.11.12 – 11:16
    рекурсия вестимо
    Drac0
    2 – 11.11.12 – 11:20
    можно через ПолноеНаименование() вытащить. это если только имя нужно.
    dclxvi
    3 – 11.11.12 – 11:21
    естьнул(Элемент.Родитель.Родитель.Родитель.Родитель.Родитель,
    естьнул(Элемент.Родитель.Родитель.Родитель.Родитель,
    естьнул(Элемент.Родитель.Родитель.Родитель,
    естьнул(Элемент.Родитель.Родитель,
    естьнул(Элемент.Родитель, &ПустаяСсылкаРодителя)))))
    RomaH
    4 – 11.11.12 – 11:24
    Функция ПриложениеПриказа302н(Знач Родитель)
    Пока Истина Цикл
    РодительВерхнегоУровня = Родитель.Родитель;
    Если ЗначениеЗаполнено(РодительВерхнегоУровня) Тогда
    Родитель = РодительВерхнегоУровня;
    Иначе
    Прервать;
    КонецЕсли;
    КонецЦикла;
    Возврат Родитель;
    КонецФункции
    типа так?
    а в запросе?
    Лефмихалыч
    5 – 11.11.12 – 11:26
    (2) ну, вытащи http://gyazo.com/3c02afa59d7e551d6a15c5eaec843107.png
    Лефмихалыч
    6 – 11.11.12 – 11:30
    1С не умеет соединять по иерархии, по этому только рекурсией
    Smallrat
    7 – 11.11.12 – 12:11
    (5) он имеет ввиду
    СправочникОбъект..ПолноеНаименование (CatalogObject..FullDescr)
    СправочникОбъект. (CatalogObject.)
    ПолноеНаименование (FullDescr)
    Синтаксис:
    ПолноеНаименование()
    Возвращаемое значение:
    Тип: Строка.
    Строка, включающая наименование элемента и наименования всех вышестоящих элементов.
    Наименования выводятся слева направо, начиная с самого верхнего уровня, разделяются символом “/”.
    Описание:
    Получает наименование элемента справочника с учетом наименований всех вышестоящих элементов.
    Доступность:
    Сервер, толстый клиент, внешнее соединение.
    RomaH
    8 – 11.11.12 – 12:24
    а может так?
    ВЫБРАТЬ
    ВредныеПроизводственныеФакторыИРаботы.Ссылка,
    ВредныеПроизводственныеФакторыИРаботы.Родитель,
    ВредныеПроизводственныеФакторыИРаботы.КодПунктаВредности
    ПОМЕСТИТЬ втВерхнийУровень
    ИЗ
    Справочник.ВредныеПроизводственныеФакторыИРаботы КАК ВредныеПроизводственныеФакторыИРаботы
    ГДЕ
    ВредныеПроизводственныеФакторыИРаботы.Родитель = &Родитель
    И ВредныеПроизводственныеФакторыИРаботы.Владелец = &Владелец
    ;
    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    ВредныеПроизводственныеФакторыИРаботы.Ссылка,
    втВерхнийУровень.Ссылка КАК Ссылка1,
    втВерхнийУровень.КодПунктаВредности
    ИЗ
    Справочник.ВредныеПроизводственныеФакторыИРаботы КАК ВредныеПроизводственныеФакторыИРаботы
    ЛЕВОЕ СОЕДИНЕНИЕ втВерхнийУровень КАК втВерхнийУровень
    ПО ВредныеПроизводственныеФакторыИРаботы.Ссылка В ИЕРАРХИИ(ВЫБРАТЬ втВерхнийУровень.Ссылка ИЗ втВерхнийУровень КАК втВерхнийУровень)
    ammpryanik
    9 – 11.11.12 – 12:25
    офигеть это знает даже такой рак как я…
    vde69
    10 – 11.11.12 – 12:31
    ВЫБРАТЬ
    Блоки.Ссылка КАК Ссылка
    ИЗ
    Справочник.Блоки КАК Блоки
    ГДЕ
    Блоки.Ссылка В ИЕРАРХИИ(&Ссылка)
    И Блоки.Родитель.Ссылка ЕСТЬ NULL
    vde69
    11 – 11.11.12 – 12:32
    (10) вру 🙂
    Мизантроп
    12 – 11.11.12 – 12:34
    Функция глРодитель(Элем) Экспорт
    Возврат ?(Элем.Уровень() = 0,Элем,глРодитель(Элем.Родитель));
    КонецФункции
    Smallrat
    13 – 11.11.12 – 12:50
    +(7) а понял. сорри
    m-serg74
    14 – 11.11.12 – 12:52
    (8) и че? получилось соединение В ИЕРАРХИИ?
    i-rek
    15 – 11.11.12 – 13:20
    а помните недавно обсуждали самый необыкновенный код ? пару недель назад тема была. Там был код в одну строку для получения родителя любого уровня
    i-rek
    16 – 11.11.12 – 13:21
    через шаблон, стрзаменить и функцию которая выдаёт N пробелов
    Smallrat
    17 – 11.11.12 – 14:04
    (16) он для 7-ки. Для 8-ки вроде не получится его в одну строку сделать – строку из заданного количества пробелов форматом не получить.
    Лефмихалыч
    18 – 11.11.12 – 14:18
    +(5) Через полное наименование можно что-то получить, только, если гарантировать, что на верхнем уровне не будет групп:
    1. С пустыми наименованиями
    2. С одинаковыми наименованиями
    3. С наименованием, содержащим “/”
    Fragster
    19 – 11.11.12 – 14:21
    http://infostart.ru/public/84547/
    Лефмихалыч
    20 – 11.11.12 – 14:25
    (17) смари
    ЗаданноеКоличествоПробелов = 46;
    ОписаниеТИповСТроки = Новый ОписаниеТипов(“Строка”,,Новый КвалификаторыСтроки(ЗаданноеКоличествоПробелов,ДопустимаяДлина.Фиксированная));
    СтрокаСЗаданнымКоличествомПробелов = ОписаниеТИповСТроки.ПривестиЗначение(“”);
    Сообщить(“”””+СтрокаСЗаданнымКоличествомПробелов+””””);
    Сообщить(“”””+СтрДлина(СтрокаСЗаданнымКоличествомПробелов)+””””);
    Bolik1979
    21 – 11.11.12 – 15:24
    Вычислить(“Номенклатура” + СтрЗаменить(Формат(0,”ЧЦ=” + Строка(Номенклатура.Уровень()) + “; ЧН=; ЧВН=; ЧГ=”), “0”, “.Родитель”))
    (с) Рупор абсурда
    Бешеная Нога
    22 – 11.11.12 – 18:10
    (21) красава 🙂
    RomaH
    23 – 12.11.12 – 07:54
    (14) да, в (8) рабочий код, в (10) – не рабочий
    RomaH
    24 – 12.11.12 – 07:54
    +(23) ну немного допилить (8) остается
    Defender aka LINN
    25 – 12.11.12 – 08:23
    Функция ПолучитьРодителя(Ссылка)
    Запрос = Новый Запрос;
    Запрос.Текст =
    “ВЫБРАТЬ
    | Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    | Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    | Контрагенты.Ссылка = &Ссылка
    |ИТОГИ ПО
    | Ссылка ТОЛЬКО ИЕРАРХИЯ”;
    Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    Выборка.Следующий();
    Возврат Выборка.Ссылка;
    КонецФункции
    Lenka_Boo
    26 – 12.11.12 – 08:35
    (0)
    1. запрос по условию ЭтоГруппа
    2. выборка из результата во временную таблицу по Результат.Ссылка.Уровень() в цикле.
    3. Временную таблицу используем дальше.
    Не?
    dmpl
    27 – 12.11.12 – 08:39
    (4) Эту функцию писали индусы.
    Мизантроп
    28 – 12.11.12 – 08:41
    Функция ПолучитьВерхнегоРодителя(Ссылка)
    Если не ЗначениеЗаполнено(Ссылка.Родитель) Тогда
    Возврат Ссылка
    Иначе
    Возврат ПолучитьВерхнегоРодителя(Ссылка.Родитель)
    КонецЕсли;
    КонецФункции
    Smallrat
    29 – 12.11.12 – 11:26
    (20) Это же две строки ?
    Smallrat
    30 – 12.11.12 – 12:44
    Попробовал переписать (21) на 8-ку
    Не получается найти замену функции Шаблон(), в 8-ке есть только аналогичная процедура.
    Получилось так:
    Перем ВерхнийРодитель;
    Выполнить(“ВерхнийРодитель = Номенклатура”+СтрЗаменить(Формат(0,”ЧЦ=” + Строка(Номенклатура.Уровень()) + “; ЧН=; ЧВН=; ЧГ=”),”0″, “.Родитель”));
    Рекламное место пустует
    Smallrat
    31 – 12.11.12 – 12:46
    мля – я надо научится читать сообщения.
    перписывал
    ЗначениеИзСтрокиВнутр(Шаблон(“[ЗначениеВСтрокуВнутр(Спр”+СтрЗаменить(Формат(“”,”С”+(Спр.Уровень()-1)),” “,”.Родитель”)+”)]”));
    Smallrat
    32 – 12.11.12 – 12:46
    а получил то что и написано в (21)
    мля((
    mikecool
    33 – 12.11.12 – 12:47
    добавить реквизит – родитель верхнего уровня
    заполнять в передзаписью в модуле
    заполнить и радоваться щастью

  2. Nibor Ответить

    Функция ВовзратЦТЗ(Дата)
    Запрос = Новый Запрос;
    Запрос.Текст = “ВЫБРАТЬ
    | Номенклатура.Ссылка КАК Номенклатура,
    | ЕСТЬNULL(СхемыЦТЗ.ЦТЗ, “”нет””) КАК ЦТЗ,
    | Номенклатура.Родитель КАК Родитель,
    | Номенклатура.ЭтоГруппа КАК ЭтоГруппа
    |ИЗ
    | Справочник.Номенклатура КАК Номенклатура
    | ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
    | СхемыЦТЗ.Ссылка КАК Ссылка,
    | ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 1
    | ТОГДА СхемыЦТЗ.Понедельник
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 2
    | ТОГДА СхемыЦТЗ.Вторник
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 3
    | ТОГДА СхемыЦТЗ.Среда
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 4
    | ТОГДА СхемыЦТЗ.Четверг
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 5
    | ТОГДА СхемыЦТЗ.Пятница
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 6
    | ТОГДА СхемыЦТЗ.Суббота
    | ИНАЧЕ ВЫБОР
    | КОГДА ДЕНЬНЕДЕЛИ(&КонецПериода) = 7
    | ТОГДА СхемыЦТЗ.Воскресение
    | КОНЕЦ
    | КОНЕЦ
    | КОНЕЦ
    | КОНЕЦ
    | КОНЕЦ
    | КОНЕЦ
    | КОНЕЦ КАК ЦТЗ
    | ИЗ
    | Справочник.СхемыЦТЗ КАК СхемыЦТЗ
    | ГДЕ
    | СхемыЦТЗ.ПометкаУдаления = ЛОЖЬ) КАК СхемыЦТЗ
    | ПО Номенклатура.Родитель.СхемаЦТЗ.Ссылка = СхемыЦТЗ.Ссылка
    |ГДЕ
    | Номенклатура.ПометкаУдаления = ЛОЖЬ”;
    Запрос.УстановитьПараметр(“КонецПериода”,Дата);
    ВыборкаУник=Запрос.Выполнить().Выгрузить();
    ТаблицаВирт=Новый ТаблицаЗначений();
    Тип=Новый ОписаниеТипов(“СправочникСсылка.Номенклатура”);
    ТаблицаВирт.Колонки.Добавить(“Номенклатура”,Тип);
    Тип=Новый ОписаниеТипов(“Число”);
    ТаблицаВирт.Колонки.Добавить(“ЦТЗ”,Тип);
    Для Каждого СтрокаВыборки из ВыборкаУник Цикл
    ОбработкаПрерыванияПользователя();
    Если СтрокаВыборки.ЭтоГруппа Тогда
    Продолжить;
    КонецЕсли;
    виртСтрока=ТаблицаВирт.Добавить();
    виртСтрока.Номенклатура=СтрокаВыборки.Номенклатура;
    ЦТЗ=ПолучитьСтрокуЦТЗ(СтрокаВыборки);
    виртСтрока.ЦТЗ=?(ТипЗнч(ЦТЗ)=Тип(“Число”),ЦТЗ,0);
    КонецЦикла;
    Возврат(ТаблицаВирт);
    КонецФункции
    Показать

  3. Nilage Ответить

    Mysteryyy
    08.07.10 – 09:32
    Как в запросе, либо еще как нибудь, получить родителя верхнего уровня для элемента номенклатуры, справочник имеет произвольное количество уровней.

    Grusswelle
    1 – 08.07.10 – 09:34
    Я делал типа так:
    ГДЕ
    Элемент.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.РустаяСсылка)
    Grusswelle
    2 – 08.07.10 – 09:34
    * ПустаяСсылка
    Grusswelle
    3 – 08.07.10 – 09:35
    Ну и соединяешь потом подзапросы с условием В ИЕРАРХИИ
    Asmody
    4 – 08.07.10 – 09:38
    для кого гугл старается? яндекс зачем придумали?
    v8: Из справочника вернуть Родителя Самого Верхнего уровня.
    Grusswelle
    5 – 08.07.10 – 09:40
    Ну я как знал прямо! 🙂 Только одним запросом всё делается и без параметра с пустой ссылкой.
    :-)))
    Grusswelle
    6 – 08.07.10 – 09:41
    (4) Тьфу, блин, чего я говорю-то… Пример – отстой, КГ/АМ. Это УГ – столько раз в цикле ещё один запрос хреначить!
    Mysteryyy
    7 – 08.07.10 – 09:48
    (4) Ищу способ сделать это попроще, вдруг кто поднаторел 🙂
    hhhh
    8 – 08.07.10 – 09:55
    (7) дык, вроде даже теоретически это невозможно. Если ограничишь иерархию, допустим не более 10 уровней, тогда да. А бесконечная иерархия – как ты ее всобачишь в линейный по сути запрос? Тем более ещё и попроще.
    Serg_1960
    9 – 08.07.10 – 10:03
    Ну, если исходить не из теории, а из практики – то “бесконечная иерархия” – нонсенс. Можно в запросе предусмотреть работу всего с 256-ю уровнями – я думаю этого будет достаточно 🙂
    Asmody
    10 – 08.07.10 – 11:14
    (6) там в ветке есть несколько нормальных вариантов. и они, как ни странно, весьма просты

  4. iSmAiLoV Ответить

    Печать
    Страницы: [1] Вниз


    Автор
    Тема: Определить принадлежность номенклатуры к конкретной группе справочника (Прочитано 5471 раз)

    0 Пользователей и 1 Гость просматривают эту тему.


    1cka



    Сообщений: 154
    РЕПУТАЦИЯ: 1
    КПД: 1%
    Регистрация: 2014-01-04
    Сайт:
    Профессия: Ученик 1С

    Определить принадлежность номенклатуры к конкретной группе справочника
    « Первое сообщение: 16 Янв 2015, 15:03 »
    8.2
    Как определить в иерархическом справочнике принадлежность номенклатуры к самому верхнему уровню?
    есть ТЗ, хотелось бы условием исключить из нее ненужные позиции
    Код: [Выделить]
    Для Каждого Строка Из ТаблицаИсходныеК Цикл
    //Если Тогда
    //Сообщить(“Группа – ” + Строка.Номенклатура.ПринадлежитЭлементуГруппы);//так определяет соответственно не самую верхнюю группу
    //КонецЕсли;
    КонецЦикла;
    Реклама на этом месте


    LexaK



    Сообщений: 1758
    РЕПУТАЦИЯ: 506
    КПД: 29%
    Регистрация: 2012-05-16
    Сайт:
    Профессия: Программист 1С

    Re: Определить принадлежность номенклатуры к конкретной группе справочника
    « Ответ #1: 16 Янв 2015, 16:00 »
    самое простое,
    в иерархическом справочнике у элемента есть реквизит Родитель, это есть ссылка на ту группу в которую входит текущий элемент, Родитель в свою очередь имеет тоже поле Родитель, и так далее, пока Поле Родитель не будет пустым – это самая верхняя группа!
    вот Функция (правда не самый оптимальный вариант) (для оптимального варианта надо делать все в одном запросе, но это сложнее)
    Код: [Выделить]
    Функция ПерваяГруппа(Номенклатура)
    лкГруппа = Номенклатура;
    Пока Не лкГруппа.Родитель.Пустая() Цикл
    лкГруппа = лкГруппа.Родитель;
    КонецЦикла;
    Возврат лкГруппа;
    КонецФункции
    Добавлено: 16 Янв 2015, 16:04
    таким образом ваш цикл будет выглядеть так
    Код: [Выделить]
    Для Каждого Строка Из ТаблицаИсходныеК Цикл
    Сообщить(“Группа – ” + ПерваяГруппа(Строка.Номенклатура));
    КонецЦикла;
    Помогло? – Нажми СПАСИБО!!!


    ilyay

    1С:Специалист, 1С:Эксперт


    Сообщений: 562
    РЕПУТАЦИЯ: 103
    КПД: 18%
    Регистрация: 2011-06-09
    Сайт:
    Профессия: Разработчик 1С

    Re: Определить принадлежность номенклатуры к конкретной группе справочника
    « Ответ #2: 19 Янв 2015, 00:24 »
    Предложенное решение – стресс-тест для базы данных. Количество запросов, равное уровню иерархии, на каждом этапе цикла!
    Нужно делать одним запросом. Загрузить ТЗ (типизированную) в запрос и использовать следующие условия: выбрать НоменклатураВерхнегоУровня.ссылка поместить НоменклатураВерхнегоУровня из справочник.номенклатура как НоменклатураВерхнегоУровня где НоменклатураВерхнегоУровня.родитель = Значение(Справочник.Номенклатура.ПустаяСсылка) И НоменклатураВерхнегоУровня.ЭтоГруппа и не НоменклатураВерхнегоУровня.ПометкаУдаления // если не используются группы, то ЭтоГруппа не нужно
    затем выборка с условием номенклатура_тз.ссылка в Иерархии(выбрать ссылка из НоменклатураВерхнегоУровня)


    1cka



    Сообщений: 154
    РЕПУТАЦИЯ: 1
    КПД: 1%
    Регистрация: 2014-01-04
    Сайт:
    Профессия: Ученик 1С

    Re: Определить принадлежность номенклатуры к конкретной группе справочника
    « Ответ #3: 19 Янв 2015, 08:37 »
    у меня получилось так:
    Код: [Выделить]
    Если (Строка.Номенклатура.ПринадлежитЭлементу(Справочники.Номенклатура.НайтиПоКоду(“0001”)) = ЛОЖЬ) Тогда


    LexaK



    Сообщений: 1758
    РЕПУТАЦИЯ: 506
    КПД: 29%
    Регистрация: 2012-05-16
    Сайт:
    Профессия: Программист 1С

    Re: Определить принадлежность номенклатуры к конкретной группе справочника
    « Ответ #4: 19 Янв 2015, 10:16 »
    ilyay,
    Цитата: ilyay от 19 Янв 2015, 00:24
    Цитировать
    затем выборка с условием номенклатура_тз.ссылка в Иерархии(выбрать ссылка из НоменклатураВерхнегоУровня)
    ваше условие, всегда будет Истина для товаров в группах,
    но где здесь имя самой верхней группы?
    например такая схема группировок, где Группа1,2,3 это Родитель(и), а цифры это уровень вложенности.
    Товар1 – Группа3 – Группа2 – Группа1 – Группа0
    Товар2 – Группа2 – Группа1 – Группа0
    Товар3 – Группа3 – Группа2 – Группа1 – Группа0
    Товар4 – Группа1 – Группа0
    и т.д. вложенность группировок может быть различной и безграничной
    как вашим запросом получить такой результат
    Товар1, Группа0
    Товар2, Группа0
    Товар3, Группа0
    Товар4, Группа0
    и т.д.
    Сообщить модератору
    Re: Определить принадлежность номенклатуры к конкретной группе справочника
    « Ответ #2: Сегодня в 00:24 »
    Предложенное решение – стресс-тест для базы данных. Количество запросов, равное уровню иерархии, на каждом этапе цикла!Нужно делать одним запросом. Загрузить ТЗ (типизированную) в запрос и использовать следующие условия: выбрать НоменклатураВерхнегоУровня.ссылка поместить НоменклатураВерхнегоУровня из справочник.номенклатура как НоменклатураВерхнегоУровня где НоменклатураВерхнегоУровня.родитель = Значение(Справочник.Номенклатура.ПустаяСсылка) И НоменклатураВерхнегоУровня.ЭтоГруппа и не НоменклатураВерхнегоУровня.ПометкаУдаления // если не используются группы, то ЭтоГруппа не нужнозатем выборка с условием номенклатура_тз.ссылка в Иерархии(выбрать ссылка из НоменклатураВерхнегоУровня
    Помогло? – Нажми СПАСИБО!!!

    Реклама на этом месте
    Печать
    Страницы: [1] Вверх
    Теги:
    Форум 1С »
    Форум 1С – ПРЕДПРИЯТИЕ 8.0 8.1 8.2 8.3 8.4 »
    Конфигурирование, программирование в “1С – Предприятие 8” »
    Определить принадлежность номенклатуры к конкретной группе справочника


    Похожие темы (5)

  5. (- ..ВеРна ТеБе.. -) Ответить

    чувак
    13.09.06 – 14:03
    Например такая иерархия:
    ТОВАРЫ //1-уровень ГРУППА
    ПРОМТОВАРЫ //2-уровень ГРУППА
    ОДЕЖДА //3-уровень ГРУППА
    Брюки // 4-уровень элемент
    Как узнать что родитель самого верхного уровня элемента “Брюки” – это группа ТОВАРЫ?

    PR
    1 – 13.09.06 – 14:05
    Небольшой цикл по поиску самого верхнего родителя.
    чувак
    2 – 13.09.06 – 14:05
    (1) Как?
    Zmich
    3 – 13.09.06 – 14:08
    Функция ОпределитьВерхнегоРодителя(ТекЭлем)
    Элем = ТекЭлем;
    Пока Элем.Уровень() 1 Цикл
    Элем = Элем.Родитель;
    КонецЦикла;
    Возврат Элем;
    КонецФункции
    Моха Лёхов
    4 – 13.09.06 – 14:20
    Я бы юзал полный код, выделил бы из него то, что до левого слеша и нашел бы элемент.
    PR
    5 – 13.09.06 – 14:22
    (4) Была у меня и такая мысль, но не стал я ее писать, ибо неверная 😉
    Моха Лёхов
    6 – 13.09.06 – 14:38
    (5) Почему?
    Или запрос хитрый сделать можно попробовать.
    ВЫБРАТЬ
    *
    ИЗ
    Справочник.Номенклатура КАК Номенклатура
    ГДЕ
    &Товар В ИЕРАРХИИ(Номенклатура) И
    Номенклатура.Родитель = &ПустаяНоменклатура
    Это грубо, не проверял.
    Моха Лёхов
    7 – 13.09.06 – 14:38
    Не прокатит запрос в (6)? А может его как-нить переделать можно?
    megalodon
    8 – 13.09.06 – 14:39
    в (3) нормальный вариант. цикл или рекурсия.
    Моха Лёхов
    9 – 13.09.06 – 14:42
    (8) семерошно :).
    alexsy
    10 – 13.09.06 – 14:43
    полный код – тормозной вариант. рекурсией будет быстрее.
    можно запрос отобрать по иерархии и по ней же отсортировать и взять первый. но что быстрее работать будет, запрос или рекурсия я не знаю.
    Моха Лёхов
    11 – 13.09.06 – 14:46
    (10) про скорость не спорю. Не знаю. Но запрос – просто красиво :).
    dimoff
    12 – 13.09.06 – 14:46
    По логике 6 быстрее должно работать чем 3
    megalodon
    13 – 13.09.06 – 14:47
    самый быстрый по моему будет так:
    ВЫБРАТЬ
    Родитель.Родитель.Родитель.Родитель// и так далее ТекЭлем.Уровень() – 1
    ИЗ
    Справочник.” + ТекЭлем.Метаданные().Имя + ”
    ГДЕ
    Ссылка = &ТекЭлем”;
    alexsy
    14 – 13.09.06 – 14:48
    скорее всего все таки рекурсия быстрее. ну сколько там вложений может быть? 20? 20 раз вызвать функцию и прочитать один реквизит в ней – легко, а вот во всей выборке в иерархии может быть не одна тысяча записей…
    dimoff
    15 – 13.09.06 – 14:48
    Ещё можно построить запрос
    “Выбрать
    Ссылка.Родитель.Родитель.Родитель
    ИЗ Справочник.Номенклатура КАК Ном
    ГДЕ Ном.Ссылка = &Элемент”
    цепочка Родитель.Родитель.Родитель
    составляется в зависимости от уровня элемента.
    megalodon
    16 – 13.09.06 – 14:48
    (12) да никогда в жизни
    alexsy
    17 – 13.09.06 – 14:49
    (13) дело! 🙂
    осталось проверить что “уровень” работает не так медленно как “ПолныйКод”
    🙂
    Алгоритм
    18 – 13.09.06 – 14:51
    Если Объект.ПринадлежитЭлементу(ЭлементСсылка) Тогда
    Сообщить(“Принадлежит”);
    КонецЕсли;
    Asmody
    19 – 13.09.06 – 14:52
    сделать запрос с итогами по иерархии, потом взять из этого запроса первый элемент…
    alexsy
    20 – 13.09.06 – 14:54
    (19) если никуда не спешишь то можно и так 🙂
    Моха Лёхов
    21 – 13.09.06 – 14:56
    (19) ИМХО, долго будет.
    ОФФ: (15)(19) Мини ТЗ то вам дать по моей ветке, чтобы убедились? А то вы как-то там не появляетесь больше.
    dimoff
    22 – 13.09.06 – 14:57
    (18) Очень в кассу
    (17) Уровень скорей всего пишется непосредственно в таблицу, а не вычисляется по ссылкам, как полный код
    ares
    23 – 13.09.06 – 15:02
    (6)Не работает твой чудо запрос, я в зврплате попробовал со справочником ФИзЛица и подразделенияОгранизации
    Алгоритм
    24 – 13.09.06 – 15:04
    Ссылка = Справочники.Номенклатура.НайтиПоКоду(“000000001”);
    Пока НЕ Ссылка.Родитель.Ссылка.Пустая() Цикл
    Ссылка = Ссылка.Родитель;
    КонецЦикла;
    Сообщить(Ссылка);
    megalodon
    25 – 13.09.06 – 15:05
    хм, а уровень вообще забавно получается. вот есть у меня справочник, там нету ограничений количества уровней, но метод Уровень() для элемента 3-го уровня делает всего 1 запрос к БД (смотрит по 10-й уровень).
    Моха Лёхов
    26 – 13.09.06 – 15:05
    (23) см. тогда (15). Если уж и он не работает ….
    Я только идею дал, сам был не уверен в его работоспособности. Видать в скобках должен быть параметр, иначе нельзя сформировать таблицу.
    ares
    27 – 13.09.06 – 15:11
    (26)По (15) сразу видно что он покажет только последнюю колонку,т.е. если …..Родитель.Родитель.Родитель (10 шт) а при данном элемента родитель заканчиваеться на 5, то выведен пустую строку или пожалуеться на ошибку
    vde69
    28 – 13.09.06 – 15:16
    если надо найти для НЕСКОЛЬКИХ товаров то получить список ВСЕХ групп и в цикле проверять Товар.ПринадлежитЭлементу (Група) и Група.Уровень()=0
    Asmody
    29 – 13.09.06 – 15:17
    (28) нафига список ВСЕХ групп? достаточно групп первого уровня…
    vde69
    30 – 13.09.06 – 15:19
    (29) а как это в запросе сделать? поля уровень у справочника нет….
    Рекламное место пустует
    ares
    31 – 13.09.06 – 15:33
    Была задумка идти с конца
    ЕСТЬNULL(ПодразделенияОрганизаций.Родитель.Родитель.Родитель.Родитель.Родитель, “А тут проверка след уровня т.е на уровень меньше, и так далее” )
    Уровней не так уж много, у меня максимум 5 уровней, но эта тема почнему то не работает
    FLENDGER
    32 – 13.09.06 – 15:43
    (9) – получается, что , так как в обычных языках программирования тоже используются цилы и рекурсии, то там тоже все по 7шному 🙂
    лучше рабочее семерошное, чем неработающее восьморошное
    (0) Кроме прделоженного цикла есть еще один метод:
    Получаешь полный код текущего элемента
    отрезаешь первую часть полного кода (которая до знака /) – это код элемента верхнего уровня
    находишь элементы через НайтиПоКоду по полному коду (подставив полученный выше код)
    перебираешь эти элементы и выбираешь тот, при котором ПервоначальныйЭлемент.ПринадлежитЭлементу(ОдинИзНайденныхЭлементов)
    P.S. кода больше, но работать должно побыстрей перебора и рекурсии при больших справочниках с большим количеством вложений
    Asmody
    33 – 13.09.06 – 15:48
    (30) ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ Ссылка.Родитель=&ПустаяСсылка И Ссылка.ЭтоГруппа
    Алгоритм
    34 – 13.09.06 – 15:51
    33 Получим все верхние группы, а де брюки
    ares
    35 – 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); Тогда работает, то теряеться через один.
    Asmody
    36 – 13.09.06 – 15:57
    (35) Ёперный балет! что делать, если завтра в справочнике станет 256 уровней? (и не надо говорить, что я мудак, я это и сам знаю)
    чувак
    37 – 13.09.06 – 15:58
    Получилось, кому интересно, код:
    Группа= Справочники.ФП_Справочники.НайтиПоНаименованию(“Статьи оборотов”);
    Запрос=Новый Запрос;
    Запрос.Текст=
    “ВЫБРАТЬ
    | Ссылка
    |ИЗ
    | Справочник.Номенклатура
    |ГДЕ
    | Ссылка В ИЕРАРХИИ (&ВыбГруппа)
    | И (НЕ Номенклатура.ЭтоГруппа)
    | И ФП_Справочники.Ссылка = &Ссылка”;
    Запрос.УстановитьПараметр(“ВыбГруппа”,Группа);
    Запрос.УстановитьПараметр(“Ссылка”,Ссылка);
    Результат=Запрос.Выполнить().Выбрать();
    Если Результат.Количество()=1 тогда
    КонецЕсли;
    ares
    38 – 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. Так ты ж сам указал родителя самого верхнего уровня 🙂
    vde69
    42 – 13.09.06 – 16:00
    (33) согласен… можно наше совместное решение отдать Гению1С и в КЗ
    Asmody
    43 – 13.09.06 – 16:00
    (37) и что ты тут проверил? как это у тебя проверяется принадлежность элемента одного справочника к группе другого справочника?
    ares
    44 – 13.09.06 – 16:01
    (39)Это очень хорошо , но здесь спор идет как это все чисто в запросе написать и быстрее это будет чем програмно, а то что ты предложил будет дольше и перовго варианта и второго, ну насчет второго точно
    Asmody
    45 – 13.09.06 – 16:01
    (38) сделать?
    чувак
    46 – 13.09.06 – 16:02
    (43),(44) Извиняюсь я немножко пьян. Вот так наверно:
    Группа= Справочники.Номенклатура.НайтиПоНаименованию(“Товары”);
    Запрос=Новый Запрос;
    Запрос.Текст=
    “ВЫБРАТЬ
    | Ссылка
    |ИЗ
    | Справочник.Номенклатура
    |ГДЕ
    | Ссылка В ИЕРАРХИИ (&ВыбГруппа)
    | И (НЕ Ссылка.ЭтоГруппа)
    | И Ссылка.Ссылка = &Ссылка”;
    Запрос.УстановитьПараметр(“ВыбГруппа”,Группа);
    Запрос.УстановитьПараметр(“Ссылка”,Ссылка);
    Результат=Запрос.Выполнить().Выбрать();
    Если Результат.Количество()=1 тогда
    КонецЕсли;
    ares
    47 – 13.09.06 – 16:02
    (45) можно….,можно и в космос полететь, только кому это нужно, согласись?
    PR
    48 – 13.09.06 – 16:03
    (6) Потому что уникальность кодов может быть отключена :))
    чувак
    49 – 13.09.06 – 16:05
    (41) Вопрос как раз так и ставился: Принадлежить ли элемент к такой группе?
    Asmody
    50 – 13.09.06 – 16:06
    (46) я правильно понимаю, что этот код заменяет метод ПринадлежитЭлементу() ?
    чувак
    51 – 13.09.06 – 16:07
    (50) метод ПринадлежитЭлементу() указывает только родителя верхного уровня, а не самого верхного
    PR
    52 – 13.09.06 – 16:07
    Мля, ну вы и развели бодягу с простого вопроса :o)
    Вариантов два: рекурсия и запрос с условиями, независимый от количества уровней.
    Оба озвучены.
    Есть возможно и другие, но нах?
    Asmody
    53 – 13.09.06 – 16:07
    (51) чего?!!!
    ares
    54 – 13.09.06 – 16:09
    (52) Ну раз ты такой умный, предложи запрос с выводом верхнего родителя. При том что в звпросе нужно указать только элемент родителя которого мы и ищем.
    чувак
    55 – 13.09.06 – 16:11
    (53) Хмм… да , не узнал что ест такой зверь.
    Пасибо! Пойду продолжу пить
    ares
    56 – 13.09.06 – 16:11
    Но то что развели из простого вопроса это что то, просто хочеться решить этот вопрос универсально(идеально). А просто решить я проблеем не вижу, немного запросов , немного кода и все готово. А охото запросом и только запросом
    FLENDGER
    57 – 13.09.06 – 16:29
    (51) зря ты так думаешь 🙂
    FLENDGER
    58 – 13.09.06 – 16:33
    да не получится в запросе для неограниченного количества уровней, так как в иерархии работает только в обратную сторону
    PR
    59 – 13.09.06 – 16:34
    (54) Его уже озвучили, читай ветку
    PR
    60 – 13.09.06 – 16:35
    (58) Все получится :))
    Asmody
    61 – 13.09.06 – 16:37
    (60) ну ка, текст в студию! то что в (6) не сработает 100%
    ares
    62 – 13.09.06 – 17:22
    (61) см. (23) я проверял ))
    PR
    63 – 13.09.06 – 17:49
    (13), (19) например. Железные варианты, проверил :))
    Neco
    64 – 13.09.06 – 18:38
    Как вариант:
    ВЫБРАТЬ ПЕРВЫЕ 1
    Подразделения.Ссылка КАК Ссылка,
    Подразделения.Представление
    ИЗ
    Справочник.Подразделения КАК Подразделения
    ГДЕ
    Подразделения.Ссылка = &Ссылка
    ИТОГИ ПО
    Ссылка ТОЛЬКО ИЕРАРХИЯ
    PVasili
    65 – 13.09.06 – 19:49
    (36)больше 10 уровней в справочнике,imho, и даунов только может быть..
    самый быстрый вариант через запрос типа родитель.родитель.родитель или родитель.родитель
    Максимальный уровень(реальный а не из конфигуратора)можно запросом.На итланд был пример.При 100000 записей <1сек работал 🙂
    PR
    66 - 13.09.06 - 19:59
    (64) Спорим, ты не проверял свой неработающий вариант?
    Рекламное место пустует
    PR
    67 - 13.09.06 - 20:00
    (65) Не, дауны - это те, кто не способен придумать такой пример :))
    Neco
    68 - 13.09.06 - 20:36
    (66) Проверил на справочнике "Подразделения" в УПП в консоли отчетов - выдает группировку последнего уровня
    PR
    69 - 13.09.06 - 21:30
    (68) А, ну да, что-то я перепутал, ты же в запросе всю иерархию тянешь :o)
    Некрасиво получается, всю иерархию тянешь, хотя нужен один элемент и неуниверсально, родитель уровня n уже так просто не вытянешь :O)
    FLENDGER
    70 - 14.09.06 - 10:26
    (64) - норма!!! респект!!!
    в принципе альтернатива другим алгоритмам...
    (69) - ну вытянет он 10-20 элементов, из которых получит только первый? думаю не очень долго будет - порядка пару долей сек...
    Зато что-то типа Родитель.Родитель.Родитель... и пр. 🙂 - это конечно круто
    может и элементы справочника будем перебирать руками (прям поэлементно, даже не используя Выбрать и пр.)?
    Вытянет он родителя уровня N - это будет N-й оператор Следующий() для выборки

  6. Moran Ответить

    В предыдущей статье был рассмотрен прием «матричного умножения» в расчете транзитивного замыкания отношений, его теоретическое обоснование и реализация на платформе «1С:Предприятие 8» на примере замыкания иерархии справочника. Из-за того, что данный прием хорошо ложится на возможности конструирования текста запроса на языке 1С, получаемый с использованием этого приема код оказывается очень компактным (всего 9 строк!) и быстрым. Возможно, у кого-то могло сложиться впечатление, что решением одной экзотической задачи с непонятным названием область применения рассмотренного метода и ограничивается. Однако, ЭТО НЕ ТАК! Существуют более приземленные практические задачи, где с большой выгодой можно применить разработанный прием построения запроса. В данной статье рассмотрены сразу пять таких задач.

    1. Быстрое определение уровней всех элементов справочника одним пакетным запросом.

    При использовании объектной модели для получения уровня элемента иерархического справочника можно использовать функцию «Уровень». Она показывает уровень вложенности текущего элемента справочника, при этом элементы в корне иерархии, вообще не имеющие родителей, имеют уровень «0».
    У этой функции два недостатка. Во-первых, она медленно выполняется. Почему это так, понять несложно, если вспомнить, как хранится иерархия в таблицах СУБД. Во-вторых, функция «Уровень» не работает в запросе. А этого как раз очень часто и не хватает: наличие колонки, содержащей уровень иерархии элемента, упростило бы решение многих задач запросами.
    Выходом может быть использование следующего запроса и построенной на нем функции
    Функция УровниИерархии(ИмяСправочника, МаксимальнаяДлинаПути) Экспорт
    Пролог = “ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ Справочник.Номенклатура
    | ГДЕ Родитель Значение(Справочник.Номенклатура.ПустаяСсылка)
    | ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ Справочник.Номенклатура;”;
    Рефрен = “ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;”;
    Эпилог = “ВЫБРАТЬ КОЛИЧЕСТВО(НачалоДуги) – 1 Предок, КонецДуги Потомок ИЗ ЗамыканияДлины#2 СГРУППИРОВАТЬ ПО КонецДуги”;
    Запрос = Новый Запрос(СтрЗаменить(Пролог, “Номенклатура”, ИмяСправочника));
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0")); МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий КонецЦикла; Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")); Возврат Запрос.Выполнить().Выгрузить() КонецФункции Запрос в данной функции отличается от базового запроса из основной статьи только эпилогом. Работа функции построена на следующем наблюдении: так как таблица транзитивного замыкания содержит всех предков любого элемента, то, чтобы определить его уровень, нужно просто посчитать этих предков. Разумеется, сконструированный внутри функции текст запроса не обязательно сразу выполнять. Его можно сделать частью более общего пакетного запроса, в котором будет использоваться получаемая на последнем этапе таблица. Это касается и всех следующих примеров. Рассмотрим, для примера, следующую иерархию номенклатуры:
    Замыкание иерархии вернет следующую таблицу:

    Приведенная функция на основе подсчета предков в замыкании вернет следующую таблицу:

    2. Быстрое определение максимальной глубины иерархии одним пакетным запросом.

    Данная задача может возникнуть, например, при выводе иерархических списков, когда требуется заранее определить «высоту» (число этажей) отображения списка. Трудность задачи в том, что приходится просматривать все элементы справочника, для каждого из которых необходим вызов функции «Уровень». Хотя такой код весьма прост,
    Функция МаксимальныйУровеньСправочника(ИмяСправочника, Ответ = 0) Экспорт
    Выборка = Справочники[ИмяСправочника].Выбрать();
    Пока Выборка.Следующий() Цикл Ответ = Макс(Ответ, Выборка.ПолучитьОбъект().Уровень())
    КонецЦикла;
    Возврат Ответ
    КонецФункции
    время его выполнения сильно и неприятно удивляет. В прилагаемой к статье обработке есть кнопка «Ой, глубина», которая вызывает написанную таким образом функцию и позволяет убедиться в большом времени ее работы. Конечно, можно использовать рекурсию, загрузив весь справочник в оперативную память, однако на больших справочниках применение рекурсии также будет не столь эффективным из-за большого количества отдельных вычислений. Пример использования рекурсии приведен здесь [http://nashe1c.ru/materials-view.jsp?id=371]. Решение не образцовое, однако доказывает интерес к данной теме.
    В результате, наилучшим решением оказывается использование предлагаемого запроса в следующем виде:
    Функция ГлубинаИерархии(ИмяСправочника, МаксимальнаяДлинаПути) Экспорт
    Пролог = “ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ Справочник.Номенклатура
    | ГДЕ Родитель Значение(Справочник.Номенклатура.ПустаяСсылка)
    | ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ Справочник.Номенклатура;”;
    Рефрен = “ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;”;
    Эпилог = “ВЫБРАТЬ ПЕРВЫЕ 1 КОЛИЧЕСТВО(НачалоДуги) – 1 Глубина, КонецДуги Потомок ИЗ ЗамыканияДлины#2 СГРУППИРОВАТЬ ПО КонецДуги УПОРЯДОЧИТЬ ПО КОЛИЧЕСТВО(НачалоДуги) – 1 УБЫВ”;
    Запрос = Новый Запрос(СтрЗаменить(Пролог, “Номенклатура”, ИмяСправочника));
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0")); МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий КонецЦикла; Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")); Возврат Запрос.Выполнить().Выгрузить()[0].Глубина КонецФункции Для краткости, случай, когда в справочнике нет ни одного элемента, не рассматривается. Для того же примера глубина будет равна 3

    3. Определение прародителя (родителя верхнего уровня) в пакетном запросе.

    Судя по обсуждениям на форумах, этот вопрос встречается достаточно часто. Широко известно решение, использующее итоги по иерархии [в комментарии (6) к предыдущей статье]. Однако оно не подходит для того, чтобы использоваться в середине пакетного запроса, не дает простой возможности одновременного определения родителей верхнего уровня нескольких элементов и, вероятно, не работает максимально быстро. От этих недостатков свободно следующее решение
    Функция Прародители(ИмяСправочника, МаксимальнаяДлинаПути) Экспорт
    Пролог = “ВЫБРАТЬ Родитель НачалоДуги, Ссылка КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ Справочник.Номенклатура
    | ГДЕ Родитель Значение(Справочник.Номенклатура.ПустаяСсылка)
    | ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка, Ссылка ИЗ Справочник.Номенклатура;”;
    Рефрен = “ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;”;
    Эпилог = “ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ИЗ ЗамыканияДлины#2
    | ГДЕ НачалоДуги КонецДуги И НачалоДуги.Родитель = Значение(Справочник.Номенклатура.ПустаяСсылка)”;
    Запрос = Новый Запрос(СтрЗаменить(Пролог, “Номенклатура”, ИмяСправочника));
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0")); МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий КонецЦикла; Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")); Возврат Запрос.Выполнить().Выгрузить() КонецФункции Для того же примера...

    4. Быстрое определение циклов произвольной длины одним пакетным запросом.

    Определение циклов основано на следующей идее:
    Будем считать уровнем элемента количество прямо или косвенно «предшествующих» ему других элементов (в смысле конкретного отношения). Такой уровень на основе таблицы транзитивного замыкания легко посчитать для ориентированного графа любого вида. Нетрудно догадаться, что уровень всех элементов, находящихся в цикле, будет одинаков. Тогда признаком того, что дуга принадлежит циклу, будет одинаковый уровень ее концов.
    В результате получаем следующий запрос, находящий дуги, принадлежащие циклу.
    Функция ЦиклыСпецификацийУПП(МаксимальнаяДлинаПути) Экспорт
    Пролог = “ВЫБРАТЬ Выход.Номенклатура НачалоДуги, Вход.Номенклатура КонецДуги, Выход.Ссылка ПОМЕСТИТЬ ИсходноеОтношение
    | ИЗ Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК Выход
    | СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК Вход ПО Выход.Ссылка = Вход.Ссылка
    | ГДЕ Выход.Ссылка.Активная;
    | ВЫБРАТЬ РАЗЛИЧНЫЕ НачалоДуги, КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ ИсходноеОтношение
    | ОБЪЕДИНИТЬ ВЫБРАТЬ НачалоДуги, НачалоДуги ИЗ ИсходноеОтношение
    | ОБЪЕДИНИТЬ ВЫБРАТЬ КонецДуги, КонецДуги ИЗ ИсходноеОтношение;”;
    Рефрен = “ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;”;
    Эпилог = “ВЫБРАТЬ КОЛИЧЕСТВО(НачалоДуги) Уровень, КонецДуги Элемент ПОМЕСТИТЬ ТаблицаУровней ИЗ ЗамыканияДлины#2 СГРУППИРОВАТЬ ПО КонецДуги;
    | ВЫБРАТЬ ИсходноеОтношение.НачалоДуги Предок, ИсходноеОтношение.КонецДуги Потомок, ИсходноеОтношение.Ссылка Спецификация ИЗ ИсходноеОтношение
    | СОЕДИНЕНИЕ ТаблицаУровней КАК Начало ПО ИсходноеОтношение.НачалоДуги = Начало.Элемент
    | СОЕДИНЕНИЕ ТаблицаУровней КАК Конец ПО ИсходноеОтношение.КонецДуги = Конец.Элемент
    | ГДЕ Начало.Уровень = Конец.Уровень”;
    Запрос = Новый Запрос(Пролог);
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0")); МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий КонецЦикла; Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")); Возврат Запрос.Выполнить().Выгрузить() КонецФункции Запрос приведен на примере проверки зацикливания спецификаций продукции для типовой конфигурации «1С: Управление производственным предприятием». Приведенная функция выдает список связей входов и выходов спецификаций, находящихся в цикле вместе с указанием самих спецификаций. Очевидно, что ошибочной (приводящей к зацикливанию) будет, вероятнее всего, только одна из указанных связей. Можно не ограничиваться только сборочными спецификациями. Но следует учесть, что в этом общем случае могут существовать и правильные циклы сборки-разборки, которые запрос также будет показывать. Понятно, что такой подход будет обнаруживать циклы любой длины. Безошибочно ограничивать максимальную длину пути можно количеством активных спецификаций, как и сделано в прилагаемой обработке. Для примера приведен набор спецификаций, содержащий циклы. Это спецификация структуры всем известной детской песни "Вместе весело шагать"
    “Песенка” получается по двум спецификациям: С1(Словечко1 + Словечко2) и С2(Куплет1 + Куплет2 + Куплет3).
    Функция, обнаруживающая циклы, вернет следующую таблицу

    5. Определение множества взаимозаменяемых позиций (аналогов) номенклатуры.

    Существует несколько решений для хранения информации о взаимозаменяемости номенклатурных позиций [//infostart.ru/public/128065/]. Например, в УПП для этого используется регистр сведений «АналогиНоменклатуры», в записях которого указывается собственно номенклатура и заменяющий ее аналог (назначение других полей этих записей для данного обсуждения не существенно). Чаще всего можно считать, что если для детали “А” аналогом является деталь “Б”, то верно и обратное: для детали “Б” аналогом будет деталь “А”. Кроме того, если деталь “Б” является аналогом детали “А”, а деталь “В” является аналогом детали “Б”, то деталь “В” также будет аналогом детали “А”.
    Как же следует задавать аналоги: по цепочке “А”->”Б”, ”Б”->”В” или звездой “А”->“Б”, ”А”->“В”? – Предлагаемый метод позволяет не задумываться об этом. В любом случае будут найдены все аналоги каждой номенклатуры. Для этого используется функция
    Функция ТранзитивноеЗамыканиеАналогии(МаксимальнаяДлинаПути) Экспорт
    Пролог = “ВЫБРАТЬ Номенклатура КАК НачалоДуги, Аналог КАК КонецДуги ПОМЕСТИТЬ ЗамыканияДлины1 ИЗ РегистрСведений.АналогиНоменклатуры
    | ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Аналог, Номенклатура ИЗ РегистрСведений.АналогиНоменклатуры
    | ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Номенклатура, Номенклатура ИЗ РегистрСведений.АналогиНоменклатуры;”;
    Рефрен = “ВЫБРАТЬ РАЗЛИЧНЫЕ ПерваяДуга.НачалоДуги, ВтораяДуга.КонецДуги ПОМЕСТИТЬ ЗамыканияДлины#2 ИЗ ЗамыканияДлины#1 КАК ПерваяДуга
    | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЗамыканияДлины#1 КАК ВтораяДуга ПО ПерваяДуга.КонецДуги = ВтораяДуга.НачалоДуги;
    | УНИЧТОЖИТЬ ЗамыканияДлины#1;”;
    Эпилог = “ВЫБРАТЬ НачалоДуги Предок, КонецДуги Потомок ИЗ ЗамыканияДлины#2 ГДЕ НачалоДуги КонецДуги”;
    Запрос = Новый Запрос(Пролог);
    МаксимальнаяДлинаЗамыканий = 1;
    Пока МаксимальнаяДлинаЗамыканий < МаксимальнаяДлинаПути Цикл Запрос.Текст = Запрос.Текст + СтрЗаменить(СтрЗаменить(Рефрен, "#1", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")), "#2", Формат(2 * МаксимальнаяДлинаЗамыканий, "ЧГ=0")); МаксимальнаяДлинаЗамыканий = 2 * МаксимальнаяДлинаЗамыканий КонецЦикла; Запрос.Текст = Запрос.Текст + СтрЗаменить(Эпилог, "#2", Формат(МаксимальнаяДлинаЗамыканий, "ЧГ=0")); Возврат Запрос.Выполнить().Выгрузить() КонецФункции Используя данный запрос, можно существенно сэкономить на хранении информации об аналогах. То есть, вместо указания для каждой номенклатуры всех ее аналогов, можно указать основную позицию и ее заменители «звездой», либо задать аналоги по цепочке, либо пользуясь комбинацией этих подходов – в виде дерева. В результате будет храниться только «остов» отношения аналогии. Например, если в группе взаимозаменяемости 100 деталей, то по максимуму потребуется ввести 100х99 = 9900 записей типа номенклатура-аналог, а в случае хранения только основных записей потребуется хранить всего 99 записей! На следующем рисунке приведены примеры аналогов. Красным обозначены связи, которые не хранятся в БД.
    В УПП понадобится 5 записей регистра сведений “Аналоги номенклатуры” для этих связей.

    После транзитивного замыкания аналогии будет сформирована полная таблица аналогов

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

  7. Tempolgin Ответить

    Хромаков



    Jan 29 2007, 11:19
    Сообщение
    #3
    Продвинутый

    Группа: Пользователи
    Сообщений: 335
    Регистрация: 29-June 05
    Пользователь №: 4455

    Цитата(SirStefan @ Jan 29 2007, 10:31) [snapback]95563[/snapback]
    Пишу запрос. Нужно получить самого верхнего родителя. Реализовал после запроса в ТЗ. Как это можно реализовать в самом теле запроса?
    Сейчас код такой:
    Код
    Для Каждого СтрокаРез ИЗ ТаблицаРезультат Цикл
    перМесто = СтрокаРез.МестоХранения;
    Пока перМесто.Уровень()>0 Цикл
    перМесто = перМесто.Родитель;
    КонецЦикла;
    СтрокаРез.Зона = перМесто;
    КонецЦикла;
    ВЫБОР КОГДА МестоХранения.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения
    КОГДА МестоХранения.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель
    КОГДА МестоХранения.Родитель.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель.Родитель
    КОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель.Родитель.Родитель
    КОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель
    КОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель.Родитель
    КОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = &ПустаяСсылка
    ТОГДА МестоХранения.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель

    КОНЕЦ КАК РодительВерхнегоУровня

  8. LoveRepeater Ответить

    ВЫБРАТЬ
    Номенклатура.Ссылка,
    ВЫБОР
    КОГДА Номенклатура.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель
    КОГДА Номенклатура.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель
    КОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
    ТОГДА Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель.Родитель
    КОНЕЦ КАК РодительВерхнегоУровня
    ИЗ
    Справочник.Номенклатура КАК Номенклатура

  9. Dourn Ответить

    В языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться иерархическими итогами, однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями. Пример:
    Код 1C v 8.х ТекущийЭлементНоменклатуры = ЭлементНоменклатура;
    Запрос = Новый Запрос(“ВЫБРАТЬ
    | Номенклатура.Родитель,
    | Номенклатура.Родитель.Родитель,
    | Номенклатура.Родитель.Родитель.Родитель,
    | Номенклатура.Родитель.Родитель.Родитель.Родитель,
    | Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель
    |ИЗ
    | Справочник.Номенклатура КАК Номенклатура
    |
    |ГДЕ
    | Номенклатура.Ссылка = &ТекущийЭлементНоменклатуры”;
    Пока Истина Цикл
    Запрос.УстановитьПараметр(“ТекущийЭлементНоменклатуры”, ТекущийЭлементНоменклатуры);
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
    Прервать;
    КонецЕсли;
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    Для НомерКолонки = 0 По Результат.Колонки.Количество() – 1 Цикл
    ТекущийЭлементНоменклатуры = Выборка[НомерКолонки];
    Если ТекущийЭлементНоменклатуры = Справочники.Номенклатура.ПустаяСсылка() Тогда
    Прервать;
    Иначе
    Сообщить(ТекущийЭлементНоменклатуры);
    КонецЕсли;
    КонецЦикла;
    Если ТекущийЭлементНоменклатуры = Справочники.Номенклатура.ПустаяСсылка() Тогда
    Прервать;
    КонецЕсли;
    КонецЦикла;
    В данном примере в окно служебных сообщений выводятся все родители для ссылки, записанной в переменную ЭлементНоменклатура. В цикле выбирается по 5 родителей ссылки.
    Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.

  10. TpaKToPuc Ответить

    LivingStar
    16.09.14 – 11:36
    в справочнике есть иерархия
    как в независимости от вложенности
    получать всегда самого верхнего родителя элемента?

    ДенисЧ
    1 – 16.09.14 – 11:37
    циклом
    Dedal
    2 – 16.09.14 – 11:40
    http://infostart.ru/public/160707/
    Maxus43
    3 – 16.09.14 – 11:40
    рекурсией
    Dmitriy_76
    4 – 16.09.14 – 11:41
    полныйКод() не ?
    akaBrr
    5 – 16.09.14 – 11:41
    я бы сначала получил группы 1 уровня, а потом проверял на вхождение
    ObjectRelationModel
    6 – 16.09.14 – 11:43
    в 1С это сделано через Ж
    ИС-2
    7 – 16.09.14 – 11:45
    запросом вывести иерархию, взять первый элемент
    DmitriyDI
    8 – 16.09.14 – 11:46
    РодительВерхнегоУровня (TopLevelParent)
    Использование:
    Чтение и запись.
    Описание:
    Тип: СправочникСсылка.
    Содержит родителя верхнего уровня.
    Доступность:
    Толстый клиент.
    Maxus43
    9 – 16.09.14 – 11:48
    (8) забыл добавить
    Расширение табличного поля списка справочника (Catalog list table box extension)
    хрен оно где работает, кроме списка
    LivingStar
    10 – 16.09.14 – 11:52
    есть элемент, вывожу его, что бы на его место вывести родителя верхнего уровня, только применять запрос если?
    ObjectRelationModel
    11 – 16.09.14 – 11:53
    какая задача в целом?
    Maxus43
    12 – 16.09.14 – 12:02
    (10) запросом это как раз фиг получится нормально
    LivingStar
    13 – 16.09.14 – 12:07
    (11) выбран контрагент, он может быть в разной вложенности находиться, но самый верхний каталог это город, название папки, нужно её получить.
    Maxus43
    14 – 16.09.14 – 12:08
    (13) контактная инфа есть у контриков… странный учет у вас
    Maxus43
    15 – 16.09.14 – 12:09
    см с (1) по (5), выбирай
    LivingStar
    16 – 16.09.14 – 12:09
    там структура каталогов сделана
    Эльниньо
    17 – 16.09.14 – 12:11
    В семёре сделал бы:
    1. Рекурсия
    2. ПолныйКод()
    el7cartel
    18 – 16.09.14 – 12:12
    (16) ну а в чем проблема рекурсию применить?
    el7cartel
    19 – 16.09.14 – 12:12
    где-то тема даже с примером есть…
    ДенисЧ
    20 – 16.09.14 – 12:16
    А рекурсия-то тут зачем…
    LivingStar
    21 – 16.09.14 – 12:28
    (20) в справочнике контрагенты каталог, в нем каталоги города, а в них может быть элементы в разной вложенности
    получается нужно получить название каталога второго с верху по иерархии
    ДенисЧ
    22 – 16.09.14 – 12:36
    (21) Я спрашиваю, не что получить, а зачем применять рекурсию ))
    LivingStar
    23 – 16.09.14 – 12:39
    (22) знаете как это правильнее получить? Что нужно применить?
    ДенисЧ
    24 – 16.09.14 – 12:42
    (23) To iterate is Human, to recurse Devine
    Ты же не считаешь себя богом?
    Пушкин
    25 – 16.09.14 – 12:47
    Одним запросом, слабо?!
    Андрюха
    26 – 16.09.14 – 12:50
    Да можно ж не запросом, а в цикле, пока ЗначениеЗаполнено(ТекущийРодитель.Родитель), не?
    Drac0
    27 – 16.09.14 – 12:52
    (26) И зачем запросы в цикле делать? Лучше запросом: и быстрее и проще.
    anatoly
    28 – 16.09.14 – 12:53
    (25) если можно условие:
    ГДЕ &контр В ИЕРАРХИИ(спр.ссылка)
    И спр.ссылка.родитель = &пустая
    то получится. но не уверен. пробовать лень ))
    Андрюха
    29 – 16.09.14 – 12:55
    Да почему в цикле запрос? Я имел в виду:
    ТекущийРодитель = Контрагент.Родитель;
    Пока ЗначениеЗаполнено(ТекущийРодитель.Родитель) Цикл
    ТекущийРодитель = ТекущийРодитель.Родитель;
    КонецЦикла;
    Сообщить(“Родитель верхнего уровня: ” + ТекущийРодитель);
    Drac0
    30 – 16.09.14 – 12:57
    (29) Ты думаешь, там не запрос? 🙂
    Рекламное место пустует
    Maxus43
    31 – 16.09.14 – 12:58
    дарю :)))
    Процедура КнопкаВыполнитьНажатие(Кнопка)
    РодительВерхнегоУровня = Неопределено;
    ПолучитьРодителя(Ссылка, РодительВерхнегоУровня);
    КонецПроцедуры
    Процедура ПолучитьРодителя(Элемент, РодительВерхнегоУровня)
    Если Не Элемент.Родитель.Пустая() Тогда
    ПолучитьРодителя(Элемент.Родитель, РодительВерхнегоУровня)
    Иначе
    РодительВерхнегоУровня = Элемент;
    КонецЕсли;
    КонецПроцедуры
    Kamas
    32 – 16.09.14 – 12:59
    (30) там все запрос этож бд
    Kamas
    33 – 16.09.14 – 13:00
    (31) цикл лучше рекурсии. Ну по крайней мере мне так в школе говорили))
    Maxus43
    34 – 16.09.14 – 13:00
    научились уже запросом родителя верхнего уровня выбирать?
    Maxus43
    35 – 16.09.14 – 13:00
    (33) зависит от задачи
    Kamas
    36 – 16.09.14 – 13:13
    Стильно модно молодежно :
    Функция ВерхнийЭлемент(Контрагент)
    Запрос = Новый Запрос;
    Запрос.Текст =
    “ВЫБРАТЬ
    | Контрагенты.Ссылка
    |ИЗ
    | Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    | Контрагенты.ЭтоГруппа
    | И Контрагенты.Родитель = &ПустаяССылка”;
    Запрос.УстановитьПараметр(“ПустаяССылка”, Справочники.Контрагенты.ПустаяСсылка());
    Результат = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = Результат.Выбрать();
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Если Контрагент.ПринадлежитЭлементу(ВыборкаДетальныеЗаписи.Ссылка) тогда
    Возврат ВыборкаДетальныеЗаписи.Ссылка
    КонецЕсли;
    КонецЦикла;
    Возврат Справочники.Контрагенты.ПустаяСсылка();
    КонецФункции
    Крошка Ру
    37 – 16.09.14 – 13:18
    (36) Запрос.УстановитьПараметр(“ПустаяССылка”, Справочники.Контрагенты.ПустаяСсылка());
    Это уже не олдфажно.
    Молодежно
    ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
    Крошка Ру
    38 – 16.09.14 – 13:18
    +(37) *Это уже олдфажно
    Kamas
    39 – 16.09.14 – 13:19
    (37) согласен
    Сияющий Асинхраль
    40 – 16.09.14 – 13:23
    Без проблем. Уровень элемента ты всегда вытащишь, а зная уровень всегда можно программно сформировать запрос. Но, честно сказать, я предпочитаю (29)
    Сияющий Асинхраль
    41 – 16.09.14 – 13:28
    (40)->(34)
    Килограмм
    42 – 16.09.14 – 14:07
    Думаю, (36) лучше (29) если мало групп и\или количество уровней вложенности большое, а так самому (29) больше нравится – проще
    LivingStar
    43 – 16.09.14 – 15:49
    интересно в (31) как то можно задать что бы получить родителя второго уровня
    Fragster
    44 – 16.09.14 – 15:51
    http://infostart.ru/public/84547/
    Fragster
    45 – 16.09.14 – 15:53
    также специально для скорости – я сделал РС с измерением – ссылкой и ресурсами – Уровень, Левое значение, Правое значение
    Fragster
    46 – 16.09.14 – 15:53
    заполнение/обновеление РС в подписке
    Fragster
    47 – 16.09.14 – 15:56
    получение цепочки родителей:
    ВЫБРАТЬ РАЗЛИЧНЫЕ
    | Иерархия.Ссылка
    |ИЗ
    | РегистрСведений.Иерархия КАК Список
    | ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.Иерархия КАК Иерархия
    | ПО (Список.Ссылка В (&Ссылки))
    | И (Иерархия.ЛевоеЗначение = Список.ПравоеЗначение)
    Fragster
    48 – 16.09.14 – 15:56
    верхние родители – соответственно добавляется условие по Уровень = 1
    Fragster
    49 – 16.09.14 – 15:57
    получение всех детей также моментально, меняем меньше на больше и наоборот. Например в запросах можно использовать такое соединение.
    Fragster
    50 – 16.09.14 – 15:59
    данные для такой иерархии:
    [1с]
    Ссылка левоеЗначение ПравоеЗначение Уровень
    а 1 10 1
    -б1 2 7 2
    –в1 3 4 3
    –в2 5 6 3
    -б2 8 9 2
    [/1с]

Добавить ответ

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