1С перебрать дерево значений

Привет! Мне нужно написать процедуру для обхода дерева значений, вся проблема в том, что я не знаю количество уровней дерева, подскажите как реализовать обход дерева значений с неизвестным количеством уровней

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

Вот примеры такой процедуры:

Для обычного приложения:

Для управляемого приложения:

Для начала обхода дерева необходимо вызвать процедуру ОбойтиДеревоЗначений и передать туда верхний уровень дерева. Ну а если верхних уровней несколько, то нужно в цикле обойти их все:

Эту статью я хочу написать в виде конкретных примеров по работе с деревом значений в 1С 8.3 и 8.2.

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

Предлагаю сразу начать с примера и получить все записи из справочника «Номенклатура» в виде дерева значений.

Создание дерева значений в 1С

Проще всего это сделать с помощью запроса. Предлагаю создать внешнюю обработку 1С на управляемых формах, добавить на форму табличное поле и кнопку «Получить дерево». По действию кнопки (точнее, команды) выполним простейший запрос.

Вот пример процедуры:

Здесь стоит особенно обратить внимание на два фактора, без которых дерево не сформируется:

  • строка в запросе «ИТОГИ ПО Родитель»
  • и Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

Если не указать правильно вид обхода результата выборки по запросу, то мы получим обычную таблицу значений.

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

Получите 267 видеоуроков по 1С бесплатно:

Мы получаем структуру с подчиненными строками. Колонка «Родитель» – это группа, колонка «Номенклатура – это элемент справочника.

Читайте также:  Pycharm установка модулей python

Теперь, на мой взгляд, самое интересное. Как организовать обход дерева значений, если мы заранее не знаем, сколько уровней в нем.

Обход дерева значений с помощью рекурсии

В основном обход дерева в 1С делается с помощью рекурсии. Даже когда известно, сколько уровней в нем. С рекурсией это проще, всего около шести строк:

В результате получим такие сообщения:

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

При обходе дерева Вы можете выполнять различные действия над ним. Например:

  • подсчет итогов по группам;
  • раскраску строк по нужным параметрам;
  • удалять ненужные строки;
  • можно делать различные отборы;
  • и так далее.

Работать с деревом значений не так уж и трудно. Фактически это та же таблица значений, но здесь присутствует невидимая колонка «Родитель». Поэтому нет никаких проблем с преобразованием дерева значений в таблицу значений.

Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):

К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.

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

Читайте также:  Casio g shock 7500

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

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