Решаем задачи автоматизации
На базе программ 1С
И собственных решений
А потом обслуживаем
По разумным ценам
Автоматизация оперативного и управленческого учета, анализ и планирование торговых операций
Дерево значений является одним из популярных типов данных, часто встречающихся на формах и конфигурации. Важным его преимуществом является заложенная платформой иерархичность, которой удобно воспользоваться в некоторых ситуациях, например, осуществить поиск по определенной группе элементов или получить отдельные итоговые суммы в различных категориях. Дерево значений в 1С – достаточно эффективный инструмент, достойный, чтобы разработчики тратили на его изучение свое время.
Чтобы на управляемой форме вывести дерево значений, необходимо добавить новый реквизит, выбрать нужный тип, добавить колонки и перетащить влево. На вопрос о добавлении колонок ответьте утвердительно, и перед вами предстанет общий вид дерева значений. Чтобы увидеть какие-либо записи, необходимо добавить строки дерева значений 1С с нужными данными.
Существует несколько способов заполнения дерева значений нужными нам свойствами с определенной иерархией. Самый простой вариант – заполнить вручную, последовательно добавляя элементы и внимательно самостоятельно соблюдая иерархию. Естественно, при большом количестве элементов данный вариант не должен рассматриваться разработчиками 1С. Данный способ вывода информации состоит из следующих операторов:
На стороне сервера:
ДеревоРек = РеквизитФормыВЗначение("Дерево");
НоваяГруппа1 = ДеревоРек.Строки.Добавить();
НоваяГруппа1.ЭлементДерева = "Продукты";
НоваяГруппа1.НомерЭлемента = 1;
НоваяГруппа2 = ДеревоРек.Строки.Добавить();
НоваяГруппа2.ЭлементДерева = "Мебель";
НоваяГруппа2.НомерЭлемента = 2;
НовыйЭлемент1 = НоваяГруппа1.Строки.Добавить();
НовыйЭлемент1.ЭлементДерева = "Кефир";
НовыйЭлемент1.НомерЭлемента = 3;
НовыйЭлемент2 = НоваяГруппа1.Строки.Добавить();
НовыйЭлемент2.ЭлементДерева = "Молоко";
НовыйЭлемент2.НомерЭлемента = 4;
ЗначениеВРеквизитФормы(ДеревоРек,"Дерево");
На стороне клиента:
Группа1 = Дерево.ПолучитьЭлементы();
Строка1 = Группа1.Добавить();
Строка1.ЭлементДерева = "hand made";
Строка1.НомерЭлемента = 10;
Группа1 = Строка1.ПолучитьЭлементы();
Подстрока1 = Группа1.Добавить();
Подстрока1.ЭлементДерева = "Шкатулка";
Подстрока1.НомерЭлемента = 12;
Подстрока2 = Группа1.Добавить();
Подстрока2.ЭлементДерева = "Фенечка";
Подстрока2.НомерЭлемента = 13;
Таким способом можно оформить на управляемой форме 1С небольшое дерево значений или простую иерархию, используя цикл. Однако часто возникает задача представить на форме сложный иерархический справочник из базы данных. И здесь на помощь придет помещение результата запроса в дерево на форме. Алгоритм достаточно прост и логичен:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|
|УПОРЯДОЧИТЬ ПО
| Номенклатура ИЕРАРХИЯ";
Данные = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ЗначениеВРеквизитФормы(Данные,"ДеревоНом")
При многократном использовании управляемой формы приходится очищать реквизиты. Не является исключением и дерево значений, если нам нужно получать актуальную информацию. Полностью очистить наш реквизит можно различными способами без особых усилий программиста:
Дерево.ПолучитьЭлементы().Очистить();
ДеревоЗн = РеквизитФормыВЗначение("Дерево");
ДеревоЗн.Строки.Очистить();
ЗначениеВРеквизитФормы(ДеревоЗн, "Дерево");
Вышеперечисленные действия достаточно просты и не требуют усилий. Намного сложнее действия с конкретными строками, которые тоже необходимо использовать в работе. Ведь зачастую мы не будем иметь ни малейшего понятия о количестве строк в дереве, его иерархии, ее глубине и пр. Именно корректная работа с данными произвольной структуры требуется от качественно разработанной функциональности решения для анализа и обработки информации дерева значений.
В первую очередь, нужно научиться работать с данными, получая их из дерева. Для этого придется написать процедуру обхода строк дерева значений. Данные можно получить на сервере или клиенте, причем разница в алгоритмах будет небольшая. Ниже представлен алгоритм обхода дерева с краткими пояснениями операторов:
На клиентской стороне:
ОбойтиЭлементыДерева(Дерево.ПолучитьЭлементы());
&НаКлиенте
Процедура ОбойтиЭлементыДерева(СтрокиДерева)
Для каждого элемента Из СтрокиДерева Цикл
Сообщить(элемента.ЭлементДерева);
ВложенныеСтроки = элемента.ПолучитьЭлементы();
Если ВложенныеСтроки.Количество() > 0 Тогда
ОбойтиЭлементыДерева(ВложенныеСтроки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
На серверной стороне:
ДеревоНаСервере = РеквизитФормыВЗначение("Дерево");
ОбойтиДеревоНаСервере(ДеревоНаСервере);
&НаСервере
Процедура ОбойтиДеревоНаСервере(ДеревоНаСервере)
Для каждого строка из ДеревоНаСервере.Строки цикл
Сообщить(Строка.ЭлементДерева);
Если Строка.Строки.Количество() > 0 Тогда
ОбойтиДеревоНаСервере(Строка);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Иногда в процессе обхода строк нам может потребоваться удалить что-либо. Для этого используется метод «Удалить(_параметр_)», для которого в качестве параметра может использоваться индекс или непосредственно строка. Так как в процессе обхода вы рассматриваете все строки по отдельности, не составит труда удалить некоторые из них. Будьте внимательны, так как при удалении строки удаляются все вложенные элементы.
Также достаточно распространенной задачей является преобразование дерева значений в таблицу значений. Так как нам нельзя терять иерархию, в таблице будет на 2 поля больше, чем в дереве – добавятся идентификатор и родитель. Заполнить таблицу с сохранением структуры мы сможем с помощью рекурсивной процедуры.
Целиком алгоритм состоит из:
ПреобразоватьВТЗРекурсия(тДерево, тТаблица, Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
&НаСервере
Процедура ПреобразоватьВТЗРекурсия(тДерево, тТаблица, ГУИД)
Для Каждого тСтр Из тДерево.Строки Цикл
нСтр = тТаблица.Добавить();
нСтр.Колонка1 = тСтр.Колонка1;
нСтр.Колонка2 = тСтр.Колонка2;
нСтр.Родитель = ГУИД;
нСтр.ГУИД = Новый УникальныйИдентификатор();
Если тСтр.Строки.Количество()>0 Тогда
ПреобразоватьВТЗРекурсия(тСтр, тТаблица, нСтр.ГУИД);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Зачастую пользователям бывает мало просто добавить дерево значений в 1С на управляемую форму. Постоянно поступают запросы, чтобы была возможность посмотреть всю структуру. Для этого придется развернуть дерево значений прямо на глазах у пользователя. В 1С это можно сделать, обойдя в цикле все строки и воспользовавшись одним из их методов:
ЭлементыДерева = Дерево.ПолучитьЭлементы();
Для каждого элемента из ЭлементыДерева цикл
элементы.Дерево.Развернуть(элемента.ПолучитьИдентификатор(),Истина);
КонецЦикла;
Также могут случаться ситуации, когда нужно свернуть имеющееся дерево. Для сворачивания конкретной строки можно воспользоваться методом «Свернуть(_Строка_)», аналогичным по синтаксису вышеописанному «Развернуть()». Чтобы полностью свернуть все дерево, придется воспользоваться рекурсивной функцией. Ее код достаточно прост и поддерживает общую методологию работы с деревом значений:
&НаКлиенте
Процедура СвернутьДерево (ЭлементыДерева)
Для Каждого элемента Из ЭлементыДерева Цикл
ВлЭлементыЭлемента = элемента.ПолучитьЭлементы();
Если ВлЭлементыЭлемента.Количество() > 0 тогда
СвернутьДерево(ВлЭлементыЭлемента);
КонецЕсли;
Элементы.Дерево.Свернуть(элемента.ПолучитьИдентификатор());
КонецЦикла;
КонецПроцедуры
Одним из сложных нюансов, связанных с деревом значений, является отсутствие возможности отбора, когда родитель не удовлетворяет условию, а подчиненный элемент удовлетворяет. Нет однозначного ответа, что делать в подобных ситуациях, поэтому разработчики 1С решили не добавлять стандартную возможность фильтрации для дерева значений. Однако с этим можно справиться, разработав свою методику, например, скопировать дерево, удалить неподходящие значения и изменить иерархию.
Созданный в платформе 1С тип «Дерево значений» отлично подходит для задач отображения иерархических списков и не только. Пользуясь им грамотно, можно существенно сэкономить время и удовлетворить требования пользователей по визуализации необходимых им данных, легко загрузив данные в дерево, обойти их и отразить развернутый список на управляемой форме.
Подпишитесь на рассылку и получайте самые свежие статьи 1 раз в месяц специально для вас
«Обращение в нашу компанию гарантирует, что мы сделаем все необходимое и даже больше, чтобы вы остались довольны и рекомендовали нас своим друзьям и деловым партнерам!»
Вы успешно отправили ваше обращение для нашего директора.
Ответ поступит на адрес почты, указанной вами в форме отправки.