Перебор всех строк дерева значений в глубину

11.11.15

Разработка - Универсальные функции

Процедура и функция перебора всех строк дерева значений в глубину.

Процедура перебора всех строк дерева значений. Перебор осуществляется вглубь дерева значений. То есть, если у строки есть починенные строки, то будет выбрана первая подчиненная строка. Если и у этой строки есть подчиненные строки, то опять же будет выбрана первая подчиненная строка. Если подчиненных строк нет - будет выбрана следующая строка на том же уровне, что и текущая строка. Если нет ни подчиненных строк, ни следующих строк на том же уровне, что и текущая строка, то ищется следующая строка после родителя текущей строки. При неудаче обрабатывается родитель родителя и далее вверх по структуре дерева значений.

Представленное на картинке дерево значений через процедуру обработает строки в следующем порядке - Строка1, Строка2, Строка3, Строка4, Строка5, Строка6, Строка7, Строка8.

 

Процедура ПереборВсехСтрокДереваЗначений()
    СтрокаДЗ=СледующаяСтрокаДЗ(НужноеДеревоЗначений);
    Пока СтрокаДЗ<>Неопределено Цикл
        //
        //обработка строки дерева значений
        //
        СтрокаДЗ=СледующаяСтрокаДЗ(НужноеДеревоЗначений, СтрокаДЗ);
    КонецЦикла;
КонецПроцедуры

// Выбор следущей строки дерева значений после переданной в качестве параметра строки.
//Следующей строкой считается первая из найденных - 1)первая подчиненная строка; 2)следующая строка на уровне
//с переданной строкой; 3)следующая строка на уровне родителя переданной строки; 4)если пункт 3 не привел
//к результату, то обрабатывается родитель родителя и далее вверх по иерархии дерева значений.
//Если переданная в качестве параметра строка является последней в дереве значений, то вернется Неопределено.
//
// Параметры:
//  текДЗ - ДеревоЗначений - днерево значений в котором осуществляется выбор следующей строки
//  текСтрокаДЗ - Неопределено - выбор первой строки корня дерева значений
//              - СтрокаДереваЗначений - строка дерева значений после котрой необходимо найти следующую строку
//
// Возвращаемое значение:
//  Неопределено - после переданной строки дерева значений отсутствуют строки или в дереве значений строки отсутствуют.
//  СтрокаДереваЗначений - следующая строка в дереве значений, расположенной после переданной строки дерева значений,
//                         либо первая строка корня дерева значений (если переданная строка дерева значений равна Неопределено)
//
Функция СледующаяСтрокаДЗ(текДЗ, текСтрокаДЗ=Неопределено)
    СтрокаВозв = Неопределено;
    Если текСтрокаДЗ=Неопределено Тогда //с самого начала дерева значений
        СтрокаВозв = ?(текДЗ.Строки.Количество()=0, Неопределено, текДЗ.Строки[0]);
    Иначе
        Если текСтрокаДЗ.Строки.Количество()<>0 Тогда  //есть подчиненные строки - заходим внутрь
            СтрокаВозв = текСтрокаДЗ.Строки[0];
        Иначе
            ОбрабатываемаяСтрокаДЗ = текСтрокаДЗ;
            Пока ОбрабатываемаяСтрокаДЗ<>Неопределено Цикл
                РодительОбрабСтрДЗ = ОбрабатываемаяСтрокаДЗ.Родитель;
                СтрокиНаУровнеОбрабСтрокиДЗ = ?(РодительОбрабСтрДЗ=Неопределено, текДЗ.Строки, РодительОбрабСтрДЗ.Строки);
                Если СтрокиНаУровнеОбрабСтрокиДЗ.Количество()>(СтрокиНаУровнеОбрабСтрокиДЗ.Индекс(ОбрабатываемаяСтрокаДЗ)+1) Тогда
                    СтрокаВозв = СтрокиНаУровнеОбрабСтрокиДЗ[СтрокиНаУровнеОбрабСтрокиДЗ.Индекс(ОбрабатываемаяСтрокаДЗ)+1];
                    Прервать;
                Иначе
                    ОбрабатываемаяСтрокаДЗ = РодительОбрабСтрДЗ;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЕсли;
    Возврат СтрокаВозв;
КонецФункции



ps. Уточню, что данный перебор не оптимален в подавляющем большинстве случаев. В подавляющем большинстве случаев стоит использовать рекурсию (найти примеры ее в сети не составляет труда).
В каких случаях следует присмотреться к использованию данного кода:
1. При необходимости влезть в большой кусок кода. То есть то, что раньше выполнялось один раз теперь необходимо выолнять со строками дерева значений. При этом кусок кода выполняемый в цикле затруднительно вынести в отдельную процедуру/функцию из-за значительного количества переменных, которые надо будет передавать в эту выделенную процедуру/функцию.
Но даже в этом варианте можно вызовом рекурсии получить все узлы дерева значений (и поместить их, например, в список значений или массив) и затем организовать цикл. Так проще и код лаконичнее.
2. Когда дерево значений в процессе обработки меняет состав узлов. Вот тогда и становится нужна функция СледующаяСтрокаДЗ().

дерево значений перебор

См. также

Печать любых непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать любые печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

3480 руб.

22.08.2023    809    1    0    

1

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    3246    YA_418728146    3    

87

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    13266    102    sapervodichka    106    

118

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    6347    quazare    8    

103

Хитрости СКД. Часть 3

СКД Универсальные функции Платформа 1С v8.3 Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

Столкнулся с тем, что мне приходится писать гору отчетов. Во многих приходится использовать повторяющиеся приемы. Решил написать шпаргалку, которая, надеюсь пригодится не только мне. В этой статье: Объединение ячеек в отчете только на определенном уровне иерархии, Постобработка итогов в табличном документе, Скрытие колонок в зависимости от количества месяцев в периоде.

28.05.2022    7712    milkers    11    

87

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

Универсальные функции БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В очередной публикации рассмотрим некоторые базовые приемы работы с регламентными заданиями в рамках библиотеки стандартных подсистем

22.05.2022    12633    quazare    25    

57
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Diversus 2300 11.11.15 17:56 Сейчас в теме
В вашем случае рекурсией не проще?

Процедура ПереборВсехСтрокДереваЗначений(текСтрока)
  СтрокиДЗ = текСтрока.Строки;
   Для Каждого ТекСтр Из СтрокиДЗ Цикл
       // Что-то делаем со строкой
       //...
      ПереборВсехСтрокДереваЗначений(ТекСтр);
   КонецЦикла;
КонецПроцедуры
Показать


Запуск пебора:
ПереборВсехСтрокДереваЗначений(текДЗ)
karpik666; hawkmax; surikateg; ya.Avoronov; bashinsky; ojiojiowka; BigB; +7 Ответить
3. kosmo0 107 13.11.15 12:35 Сейчас в теме
(1)(2)
Как вариант если влезаете в существующий большой код.
Как необходимость если дерево значений в процессе обработки меняет состав узлов.
4. kosmo0 107 13.11.15 12:39 Сейчас в теме
(1) Вы бы хоть код корректный писали. А то хегня, а не код. Как из корня запускается то?
2. harmer 1 11.11.15 18:00 Сейчас в теме
Рекурсия? Не, не слышал.

PS http://infostart.ru/public/20797/
Процедура ИзменитьПометкиПодчиненных(пГлавный)
    Подчиненные = пГлавный.Строки;
    Для Каждого Подчиненный Из Подчиненные Цикл
        Подчиненный.Пометка = пГлавный.Пометка;
        ИзменитьПометкиПодчиненных(Подчиненный);
    КонецЦикла;
КонецПроцедуры
ya.Avoronov; BigB; +2 Ответить
5. json 3245 14.09.16 05:50 Сейчас в теме
Можно еще вот так перебрать все строки:

Функция ПолучитьВсеСтрокиДереваЗначений(Дерево) Экспорт
	ИмяВременнойКолонки = "_ВременнаяКолонка_";
	Дерево.Колонки.Добавить(ИмяВременнойКолонки);
	
	Отбор = Новый Структура(ИмяВременнойКолонки, Неопределено);
	ВсеСтрокиДерева = Дерево.Строки.НайтиСтроки(Отбор, Истина);
	
	Дерево.Колонки.Удалить(ИмяВременнойКолонки);
	
	Возврат ВсеСтрокиДерева;
КонецФункции
Показать


Пример в прищепке
Прикрепленные файлы:
ВнешняяОбработка1.epf
Оставьте свое сообщение