8.х ДеревоЗначений

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем cherva, 29 ноя 2007.

  1. TopicStarter Overlay
    cherva
    Offline

    cherva

    Регистрация:
    31 мар 2007
    Сообщения:
    16
    Симпатии:
    0
    Баллы:
    1
    Добрый день.
    Подскажите плиз, как перебрать все строки в дереве значений, включая подчиненные?
    Не могу найти метода... Знаю только методы перебора определенного уровня. Есть дерево значений, которое заполняется интерактивно, в нем может быть нефиксированное количество уровней.
  2. sergey
    Offline

    sergey Курильщик

    Регистрация:
    13 апр 2006
    Сообщения:
    365
    Симпатии:
    0
    Баллы:
    26
    На примере выборки из многоуровнего справочника:
    Код:
    Процедура КнопкаВыполнитьНажатие(Кнопка)
    МойЗапрос=новый Запрос;
    МойЗапрос.Текст="Выбрать * из Справочник.Номенклатура
    | Упорядочить По Наименование Иерархия";
    Результат=МойЗапрос.Выполнить().Выбрать();
    Пока Результат.Следующий() Цикл
    Сообщить(Результат.ссылка.ПолноеНаименование());
    КонецЦикла;    
    КонецПроцедуры
    
    
    Это выборка с иерархической сортировкой.
  3. TopicStarter Overlay
    cherva
    Offline

    cherva

    Регистрация:
    31 мар 2007
    Сообщения:
    16
    Симпатии:
    0
    Баллы:
    1
    Уважаемый sergey. Спасибо, что пытаетесь помочь, но мой вопрос заключался в другом.
    У меня есть дерево значений в форме, которое заполняется интерактивно пользователем, надо перебрать строки именно дерева значений, а не справочника. Я не могу найти метода объекта "ДеревоЗначений" которое позволило бы перебрать все его строки, есть только возможность перебрать строки текущего уровня и метод для перехода на следующий уровень, но т.к. количество уровней неизвестно, получается бардак.
  4. AlexFF
    Offline

    AlexFF Разбирающийся

    Регистрация:
    6 мар 2007
    Сообщения:
    565
    Симпатии:
    1
    Баллы:
    26
    Откуда спионерел уже и не помню. :) Но кажется это то что надо.

    Дерево значений / ver.- 8.0 /
    Дерево значений — это объект для хранения временных наборов данных, возникающих при работе программы.

    Работа с деревом значений напоминает работу с таблицей значений, за исключением того, что в дереве могут быть представлены иерархические данные (по аналогии с иерархическим справочником). Это достигается тем, что каждая строка дерева значений может иметь подчиненные строки, а те, в свою очередь, тоже могут иметь подчиненные строки и т.д.

    Дерево значений предоставляет возможность обхода строк и подсчета итогов по всем строкам дерева или по текущему уровню иерархии.

    Объект ДеревоЗначений имеет свойство Строки и Колонки, через которые осуществляется доступ к коллекции строк 1-го уровня и колонок дерева значений. У каждой строки дерева значения (т.е. объекта СтрокаДереваЗначений) есть свойство Строки, содержащее коллекцию подчиненных строк для данной строки дерева значений.

    Следующий пример создает дерево значений и наполняет его данными:

    дзОтделы = Новый ДеревоЗначений;дзОтделы.Колонки.Добавить("Отдел");дзОтделы.Колонки.Добавить("Руководитель");Нов = дзОтделы.Строки.Добавить(); //индекс 0Нов.Отдел = "Бухгалтерия";Нов = дзОтделы.Строки.Добавить(); //индекс 1Нов.Отдел = "Руководство"; //детализируем отдел "Бухгалтерия"Нов = дзОтделы.Строки[0] .Строки.Добавить ();Нов.Отдел = "Расчет зарплаты";Нов = дзОтделы.Строки[0].Строки.Добавить();Нов.Отдел = "Основные средства"; //детализируем руководствоНов = дзОтделы.Строки[1] .Строки.Добавить ();Нов.Отдел = "Высшее руководство";Нов = дзОтделы.Строки[1].Строки.Добавить();Нов.Отдел = "Отдел маркетинга"; Так же, как и с таблицей значений, можно создать полную копию деревазначений с помощью метода Скопировать: НОваяОргСтруктура = ДзОтделы.Скопировать();

    Обход строк реализуется с помощью конструкции «Для Каждого»
    или оператором [...]:

    //1-й вариант: обход строк 1-го уровня
    Для Каждого стр Из дзОтделы Цикл
    Сообщить(стр.Отдел);
    КснецЦикла;

    //2-й вариант (индексация строк начинается с 0)
    Для н = 0 По дзОтделы.Строки.Количество()-1 Цикл
    стр = дзОтделы.Строки[н];
    Сообщить(стр);
    КснецЦикла;


    Следующая программа с помощью рекурсивной процедуры обходит
    все строки дерева значений, включая подчиненные:

    Процедура ПоказатьПодчиневные (СтрокаДерева,Уровень=0)
    Для Каждого стр Из СтрокаДерева.Строки Цикл
    отступ = "";
    Для н = 1 По Уровень Цикл
    отступ = отступ + " ";
    КонецЦикла;
    Сообщить(отступ + стр.Отдел);
    ПоказатьПодчиненные(стр,Уровень+1);
    КонецЦикла;
    КонецПроцедуры


    ПоказатьПодчиненные(дзОтделы);

    Результат работы программы:

    Бухгалтерия

    Расчет зарплаты

    Основные средства

    Руководство

    Высшее руководство

    Отдел маркетинга


    Аналогично таблице значений, дерево значений позволяет искать
    значение с помощью метода Найти или искать сразу несколько
    строк методом НайтиСтроки.
    Принципы работы этих методов полностью идентичны рассмотренным
    выше для таблицы значений, за исключением последнего параметра
    ВключатьПодчиненные.
    Если передать в него значение Истина, то поиск будет производиться в
    том числе и по подчиненным строкам, иначе — только по строкам
    текущего уровня.
  5. Эмин
    Offline

    Эмин Руководитель проектов

    Регистрация:
    25 май 2007
    Сообщения:
    1.178
    Симпатии:
    1
    Баллы:
    26
    А если сделать рекурсивный перебор?
    То есть процедуру выбора Строк в ветви вызывать для каждой выбранной строки, типа такого:
    Код:
    Процедура [b]ВыбратьСтрокиВДереве[/b](Строка)
    
    Для А = 0 По Строка.Количество()-1 Цикл
    ПодСтрока = Строка.Получить(А);
    [b]ВыбратьСтрокиВДереве[/b](ПодСтрока);
    КонецЦикла;
    
    КонецПроцедуры
    
    
    А вообще советую поискать алгоритмы перебора узлов дерева - есть два основных метода (подхода) - в глубину и в ширину и это чисто математическая задача.
  6. TopicStarter Overlay
    cherva
    Offline

    cherva

    Регистрация:
    31 мар 2007
    Сообщения:
    16
    Симпатии:
    0
    Баллы:
    1
    Спасибо за помощь. О рекурсивном переборе даже и не подумал...
    Единственно, при использовании приведенной выше процедуры нужно сделать небольшое изменение:
    Строка - тип значения строка дерева, а метод количество() и получить() необходимо применять к коллекцииСтрок. В итоге получилось так:

    Процедура ВыбратьСтрокиВДереве(Строка)

    Коллекция = Строка.Строки;
    Для А = 0 По Коллекция.Количество()-1 Цикл
    ПодСтрока = Коллекция.Получить(А);
    ВыбратьСтрокиВДереве(ПодСтрока);
    КонецЦикла;

    КонецПроцедуры
  7. Эмин
    Offline

    Эмин Руководитель проектов

    Регистрация:
    25 май 2007
    Сообщения:
    1.178
    Симпатии:
    1
    Баллы:
    26
    Ну да... писал то саму схему, не задумывался особо :)

Поделиться этой страницей