Работа с деревом значений в 1С 8.3 на примерах
Эту статью я хочу написать в виде конкретных примеров по работе с деревом значений в 1С 8.3 и 8.2.
Дерево значений представляет из себя некую структуру с иерархией. У каждой строки дерева значений может быть сколько угодно подчиненных строк.
Предлагаю сразу начать с примера и получить все записи из справочника «Номенклатура» в виде дерева значений.
Создание дерева значений в 1С
Проще всего это сделать с помощью запроса. Предлагаю создать внешнюю обработку 1С на управляемых формах, добавить на форму табличное поле и кнопку «Получить дерево». По действию кнопки (точнее, команды) выполним простейший запрос.
Вот пример процедуры:
&НаСервере Процедура ПолучитьДеревоНаСервере() Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Родитель КАК Родитель, | Номенклатура.Ссылка КАК Номенклатура |ИЗ | Справочник.Номенклатура КАК Номенклатура |ИТОГИ ПО | Родитель"; ПромДерево = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией); ЗначениеВРеквизитФормы(ПромДерево, "ДеревоЗн"); КонецПроцедуры
Здесь стоит особенно обратить внимание на два фактора, без которых дерево не сформируется:
- строка в запросе «ИТОГИ ПО Родитель»
- и Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
Если не указать правильно вид обхода результата выборки по запросу, то мы получим обычную таблицу значений.
Результат вывода данного запроса 1С дерево значений на управляемую форму выглядит следующим образом:
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Мы получаем структуру с подчиненными строками. Колонка «Родитель» – это группа, колонка «Номенклатура – это элемент справочника.
Теперь, на мой взгляд, самое интересное. Как организовать обход дерева значений, если мы заранее не знаем, сколько уровней в нем.
Обход дерева значений с помощью рекурсии
В основном обход дерева в 1С делается с помощью рекурсии. Даже когда известно, сколько уровней в нем. С рекурсией это проще, всего около шести строк:
&НаКлиенте Процедура ОбходДерева(Команда) ОбойтиДеревоНаСервере(); КонецПроцедуры &НаСервере Процедура ОбойтиДеревоНаСервере() ДеревоЗнач = РеквизитФормыВЗначение("ДеревоЗн"); ОбходДереваДетально(ДеревоЗнач); КонецПроцедуры //Рекурсивная процедура &НаСервере Процедура ОбходДереваДетально(ПереданноеДер) Для Каждого СтрПолученногоДерева Из ПереданноеДер.Строки Цикл Сообщить(СтрПолученногоДерева.Номенклатура); Если СтрПолученногоДерева.Строки.Количество()>0 Тогда ОбходДереваДетально(СтрПолученногоДерева); КонецЕсли; КонецЦикла; КонецПроцедуры
В результате получим такие сообщения:
Пример данной обработки для управляемых форм можно скачать по ссылке. С помощью аналогичного кода 1С возможно преобразовать дерево значений в таблицу значений.
При обходе дерева Вы можете выполнять различные действия над ним. Например:
- подсчет итогов по группам;
- раскраску строк по нужным параметрам;
- удалять ненужные строки;
- можно делать различные отборы;
- и так далее.
Работать с деревом значений не так уж и трудно. Фактически это та же таблица значений, но здесь присутствует невидимая колонка «Родитель». Поэтому нет никаких проблем с преобразованием дерева значений в таблицу значений.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
СПРОСИТЕ в комментариях!
Serg:
Вместо «строка в запросе «ИТОГИ ПО Родитель»» лучше «УПОРЯДОЧИТЬ ПО
Родитель ИЕРАРХИЯ «.
Аноним:
Без Итогов иерархическая структура не создается
Аноним:
Так точно!
Аноним:
Лучше молчать порой чем позориться
Уфа:
Ваш код запроса не верен, исправьте на:
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.Ссылка КАК Номенклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа
|ИТОГИ ПО
| Родитель ИЕРАРХИЯ»;
ПромДерево = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ЗначениеВРеквизитФормы(ПромДерево, «ДеревоЗн»);
Александр:
ты гений
Алексей:
&НаСервере функция Сообщить() должна выдавать ошибку компиляции
Аноним:
не обязательно
справедливый:
Бред какой-то, а где программное создание дерева?
Разобран вариант создание дерева через запрос, но это же не один вариант…
Бульдак:
СтрПолученногоДерева.Строки.Количество()>0
Вечный цикл…. грамотеи….