1С 8.3 Дерево значений
Данные > Примеры кода 1С > 1С 8.3 Дерево значений
Дерево Значений в 1С 8.3 - это иерархический динамически набор любого типа. По своим функциям и структуре (колонки и строки) очень схожа с Таблицей Значений, но есть виртуальная колонка "Родитель". Дерево значений рекомендуется использовать для работы именно с иерархической информацией. Каждая строка дерева значений имеет свойства "Родитель" и "Строки", а также может иметь любое количество подчиненных строк. Операции с помощью встроенного функционала (сортировка, раскраска строк, поиск, итоги, различные отборы) могут производится с учетом подчиненных строк / уровней иерархии.
Оглавление:
Заполнение реквизита формы Дерева Значений в 1С 8.3:
&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// ДеревоЗначений = Новый ДеревоЗначений; - если без реквизита
ДЗ_Корень = ДеревоЗначений.Строки.Добавить();
ДЗ_Корень.Наименование = "Самый верхний уровень";
ДЗ_1уровень = ДЗ_Корень.Строки.Добавить();
ДЗ_1уровень.Наименование = "1-ая папка (группа)";
ЭлементДЗ_1 = ДЗ_1уровень.Строки.Добавить();
ЭлементДЗ_1.Наименование = "Первый (вложенный) элемент";
ДЗ_2уровень = ДЗ_Корень.Строки.Добавить();
ДЗ_2уровень.Наименование = "2-ая папка (группа)";
ЭлементДЗ_1 = ДЗ_2уровень.Строки.Добавить();
ЭлементДЗ_1.Наименование = "Первый (вложенный) элемент";
ЭлементДЗ_2 = ДЗ_2уровень.Строки.Добавить();
ЭлементДЗ_2.Наименование = "Второй (вложенный) элемент";
// Преобразование ДеревоЗначений в реквизит формы (табличное поле)
ЗначениеВРеквизитФормы(ДеревоЗначений,"ДеревоЗначНаФорме");
КонецПроцедуры
Процедура ЗаполнениеРеквизитаФормыДеревоЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// ДеревоЗначений = Новый ДеревоЗначений; - если без реквизита
ДЗ_Корень = ДеревоЗначений.Строки.Добавить();
ДЗ_Корень.Наименование = "Самый верхний уровень";
ДЗ_1уровень = ДЗ_Корень.Строки.Добавить();
ДЗ_1уровень.Наименование = "1-ая папка (группа)";
ЭлементДЗ_1 = ДЗ_1уровень.Строки.Добавить();
ЭлементДЗ_1.Наименование = "Первый (вложенный) элемент";
ДЗ_2уровень = ДЗ_Корень.Строки.Добавить();
ДЗ_2уровень.Наименование = "2-ая папка (группа)";
ЭлементДЗ_1 = ДЗ_2уровень.Строки.Добавить();
ЭлементДЗ_1.Наименование = "Первый (вложенный) элемент";
ЭлементДЗ_2 = ДЗ_2уровень.Строки.Добавить();
ЭлементДЗ_2.Наименование = "Второй (вложенный) элемент";
// Преобразование ДеревоЗначений в реквизит формы (табличное поле)
ЗначениеВРеквизитФормы(ДеревоЗначений,"ДеревоЗначНаФорме");
КонецПроцедуры
Заполнение реквизита формы Дерева Значений из Запроса в 1С 8.3:
&НаСервере
Процедура ЗаполнениеРеквизитаФормыДеревоЗначенийИзЗапроса()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Материалы.Ссылка КАК Наименование
| Материалы.Родитель КАК Родитель
|ИЗ
| Справочник.Материалы КАК Материалы
|УПОРЯДОЧИТЬ ПО
| Наименование ИЕРАРХИЯ
|ИТОГИ ПО
| Родитель";
//Внимание! Если правильно не указать вид обхода результата выборки по запросу,
//то мы получим обычную таблицу значений
ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
// Заполнение дерева значений из результата запроса
// колонка "Материалы" – это элемент справочника, колонка "Родитель" – это группа
ЗначениеВРеквизитФормы(ДеревоЗначений, "ДеревоЗначНаФорме"); // Преобразование в реквизит формы (табличное поле)
КонецПроцедуры
Процедура ЗаполнениеРеквизитаФормыДеревоЗначенийИзЗапроса()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Материалы.Ссылка КАК Наименование
| Материалы.Родитель КАК Родитель
|ИЗ
| Справочник.Материалы КАК Материалы
|УПОРЯДОЧИТЬ ПО
| Наименование ИЕРАРХИЯ
|ИТОГИ ПО
| Родитель";
//Внимание! Если правильно не указать вид обхода результата выборки по запросу,
//то мы получим обычную таблицу значений
ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
// Заполнение дерева значений из результата запроса
// колонка "Материалы" – это элемент справочника, колонка "Родитель" – это группа
ЗначениеВРеквизитФормы(ДеревоЗначений, "ДеревоЗначНаФорме"); // Преобразование в реквизит формы (табличное поле)
КонецПроцедуры
Поиск строки в Дереве Значений в 1С 8.3:
&НаСервере
Процедура ПоискСтрокиВДеревеЗначений() // найдём 1-ю строку со значением «Элемент №1» в дереве значений
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// Поиск строки... (если строка не найдена, вернёт "Неопределено")
НайденнаяСтрокаДЗ = ДеревоЗначений.Строки.Найти("Первый (вложенный) элемент", "Наименование", Истина);
// Анализ результата поиска
Если НайденнаяСтрокаДЗ = Неопределено Тогда
Сообщить("Строка не найдена");
Иначе // вренёт первую найденную строку
Сообщить("Найдена: "+НайденнаяСтрокаДЗ.Наименование + " (" + НайденнаяСтрокаДЗ.Родитель.Наименование + ")");
КонецЕсли;
КонецПроцедуры
Процедура ПоискСтрокиВДеревеЗначений() // найдём 1-ю строку со значением «Элемент №1» в дереве значений
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// Поиск строки... (если строка не найдена, вернёт "Неопределено")
НайденнаяСтрокаДЗ = ДеревоЗначений.Строки.Найти("Первый (вложенный) элемент", "Наименование", Истина);
// Анализ результата поиска
Если НайденнаяСтрокаДЗ = Неопределено Тогда
Сообщить("Строка не найдена");
Иначе // вренёт первую найденную строку
Сообщить("Найдена: "+НайденнаяСтрокаДЗ.Наименование + " (" + НайденнаяСтрокаДЗ.Родитель.Наименование + ")");
КонецЕсли;
КонецПроцедуры
Поиск всех строк в Дереве Значений в 1С 8.3:
&НаСервере
Процедура ПоискВсехСтрокВДеревеЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// Создаем структуру для поиска (условие)
НаименованиеДляПоиска = "Первый (вложенный) элемент";
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Наименование", НаименованиеДляПоиска);
// Поиск всех строк содержащих наименование "Первый (вложенный) элемент"
МассивСтрок_ДЗ = ДеревоЗначений.Строки.НайтиСтроки(ПараметрыОтбора, Истина);
// Проверка найдены ли строки
Если МассивСтрок_ДЗ.Количество() = 0 Тогда
Сообщить("Ни одной строкис наименованием "+НаименованиеДляПоиска+" не найдено!");
КонецЕсли;
// Перебор строк
Для Каждого Строка_ДЗ Из МассивСтрок_ДЗ Цикл
Если Строка_ДЗ.Родитель = Неопределено Тогда
Сообщить("Корень дерева значений: "+Строка_ДЗ.Наименование);
Иначе
Сообщить(Строка_ДЗ.Наименование + " - " + Строка_ДЗ.Родитель.Наименование);
КонецЕсли
КонецЦикла;
КонецПроцедуры
Процедура ПоискВсехСтрокВДеревеЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// Создаем структуру для поиска (условие)
НаименованиеДляПоиска = "Первый (вложенный) элемент";
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Наименование", НаименованиеДляПоиска);
// Поиск всех строк содержащих наименование "Первый (вложенный) элемент"
МассивСтрок_ДЗ = ДеревоЗначений.Строки.НайтиСтроки(ПараметрыОтбора, Истина);
// Проверка найдены ли строки
Если МассивСтрок_ДЗ.Количество() = 0 Тогда
Сообщить("Ни одной строкис наименованием "+НаименованиеДляПоиска+" не найдено!");
КонецЕсли;
// Перебор строк
Для Каждого Строка_ДЗ Из МассивСтрок_ДЗ Цикл
Если Строка_ДЗ.Родитель = Неопределено Тогда
Сообщить("Корень дерева значений: "+Строка_ДЗ.Наименование);
Иначе
Сообщить(Строка_ДЗ.Наименование + " - " + Строка_ДЗ.Родитель.Наименование);
КонецЕсли
КонецЦикла;
КонецПроцедуры
Удаление строки из Дерева Значений в 1С 8.3:
&НаСервере
Процедура УдалениеСтрокиИзДереваЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// С помощью данных методов возможно удаление конкретных строк
// Важно! При удалении либо очистки строки - все её подчинённые строки удалятся
// 1.Очистка всех строк
ДеревоЗначений.Строки.Очистить();
// 2. Удаление по конкретному индексу
ДеревоЗначений.Строки.Удалить(0);
// 3.Или удаление по конкретному наименованию
НайтиСтроку = ДеревоЗначений.Строки.Найти("Легированная сталь", "Наименование");
Если НЕ НайтиСтроку = Неопределено Тогда
ДеревоЗначений.Строки.Удалить(НайтиСтроку);
КонецЕсли;
ЗначениеВРеквизитФормы(ДеревоЗначений, "ДеревоЗначНаФорме"); // Преобразование в реквизит формы (табличное поле)
КонецПроцедуры
Процедура УдалениеСтрокиИзДереваЗначений()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
// С помощью данных методов возможно удаление конкретных строк
// Важно! При удалении либо очистки строки - все её подчинённые строки удалятся
// 1.Очистка всех строк
ДеревоЗначений.Строки.Очистить();
// 2. Удаление по конкретному индексу
ДеревоЗначений.Строки.Удалить(0);
// 3.Или удаление по конкретному наименованию
НайтиСтроку = ДеревоЗначений.Строки.Найти("Легированная сталь", "Наименование");
Если НЕ НайтиСтроку = Неопределено Тогда
ДеревоЗначений.Строки.Удалить(НайтиСтроку);
КонецЕсли;
ЗначениеВРеквизитФормы(ДеревоЗначений, "ДеревоЗначНаФорме"); // Преобразование в реквизит формы (табличное поле)
КонецПроцедуры
Обход Дерева Значений (с помощью рекурсии) в 1С 8.3:
&НаСервере
Процедура ОбойтиДЗ_НаСервере()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
ОбходДЗ_Рекурсия(ДеревоЗначений);
КонецПроцедуры
&НаСервере
Процедура ОбходДЗ_Рекурсия(перДеревоЗначений)
Для Каждого Строка_Рек Из перДеревоЗначений.Строки Цикл
Если Строка_Рек.Строки.Количество()>0 Тогда
ОбходДЗ_Рекурсия(Строка_Рек);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ОбойтиДЗ_НаСервере()
// Преобразование реквизита формы в объект прикладного типа ДеревоЗначений
ДеревоЗначений = РеквизитФормыВЗначение("ДеревоЗначНаФорме");
ОбходДЗ_Рекурсия(ДеревоЗначений);
КонецПроцедуры
&НаСервере
Процедура ОбходДЗ_Рекурсия(перДеревоЗначений)
Для Каждого Строка_Рек Из перДеревоЗначений.Строки Цикл
Если Строка_Рек.Строки.Количество()>0 Тогда
ОбходДЗ_Рекурсия(Строка_Рек);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Свертка всего Дерева Значений (на форме) в 1С 8.3:
&НаКлиенте
Процедура СверткаВсегоДереваЗначенийНаФорме()
// ДеревоЗначНаФорме - на форме
КоллекцияЭлементовДерева=ДеревоЗначНаФорме.ПолучитьЭлементы();
//Свернуть дерево
Для Каждого СтрокаКоллекции Из КоллекцияЭлементовДерева Цикл
ИдСтроки=СтрокаКоллекции.ПолучитьИдентификатор();
Элементы.ДеревоЗначНаФорме.Свернуть(ИдСтроки); // Сворачиваем каждую строку тут
КонецЦикла;
КонецПроцедуры
Процедура СверткаВсегоДереваЗначенийНаФорме()
// ДеревоЗначНаФорме - на форме
КоллекцияЭлементовДерева=ДеревоЗначНаФорме.ПолучитьЭлементы();
//Свернуть дерево
Для Каждого СтрокаКоллекции Из КоллекцияЭлементовДерева Цикл
ИдСтроки=СтрокаКоллекции.ПолучитьИдентификатор();
Элементы.ДеревоЗначНаФорме.Свернуть(ИдСтроки); // Сворачиваем каждую строку тут
КонецЦикла;
КонецПроцедуры
Разворот всего Дерева Значений (на форме) в 1С 8.3:
&НаКлиенте
Процедура РазворотВсегоДереваЗначенийНаФорме()
// ДеревоЗначНаФорме - на форме
КоллекцияЭлементовДерева=ДеревоЗначНаФорме.ПолучитьЭлементы();
//Развернуть дерево
Для Каждого СтрокаКоллекции Из КоллекцияЭлементовДерева Цикл
ИдСтроки=СтрокаКоллекции.ПолучитьИдентификатор();
Элементы.ДеревоЗначНаФорме.Развернуть(ИдСтроки);// Разворачиваем каждую строку тут
КонецЦикла;
КонецПроцедуры
Процедура РазворотВсегоДереваЗначенийНаФорме()
// ДеревоЗначНаФорме - на форме
КоллекцияЭлементовДерева=ДеревоЗначНаФорме.ПолучитьЭлементы();
//Развернуть дерево
Для Каждого СтрокаКоллекции Из КоллекцияЭлементовДерева Цикл
ИдСтроки=СтрокаКоллекции.ПолучитьИдентификатор();
Элементы.ДеревоЗначНаФорме.Развернуть(ИдСтроки);// Разворачиваем каждую строку тут
КонецЦикла;
КонецПроцедуры
Разворот текущей строки Дерева Значений (на форме) в 1С 8.3:
&НаКлиенте
Процедура РазворотТекСтрокиДереваЗначенийНаФорме() // Разворот текущей строки в дереве:
СтрокаДЗ = Элементы.ДеревоЗначНаФорме.ТекущаяСтрока;
Элементы.ДеревоЗначНаФорме.Развернуть(СтрокаДЗ, Истина);
// Определим, развернут ли узел дерева в указанной строке.
УзелРазвернут = Элементы.ДеревоЗначНаФорме.Развернут(СтрокаДЗ);
Если УзелРазвернут Тогда // Если узел Развернут, то Свернуть
Элементы.ДеревоЗначНаФорме.Свернуть(СтрокаДЗ);
КонецЕсли;
КонецПроцедуры
Процедура РазворотТекСтрокиДереваЗначенийНаФорме() // Разворот текущей строки в дереве:
СтрокаДЗ = Элементы.ДеревоЗначНаФорме.ТекущаяСтрока;
Элементы.ДеревоЗначНаФорме.Развернуть(СтрокаДЗ, Истина);
// Определим, развернут ли узел дерева в указанной строке.
УзелРазвернут = Элементы.ДеревоЗначНаФорме.Развернут(СтрокаДЗ);
Если УзелРазвернут Тогда // Если узел Развернут, то Свернуть
Элементы.ДеревоЗначНаФорме.Свернуть(СтрокаДЗ);
КонецЕсли;
КонецПроцедуры
Свернуть все выделенные строки Дерева Значений (на форме) в 1С 8.3:
&НаКлиенте
Процедура СвернутьВсеВыделенныеСтрокиДереваЗначенийНаФорме()
Для Каждого СтрокаДЗ Из Элементы.ДеревоЗначНаФорме.ВыделенныеСтроки Цикл
Элементы.ДеревоЗначНаФорме.Свернуть(СтрокаДЗ);
КонецЦикла;
КонецПроцедуры
Процедура СвернутьВсеВыделенныеСтрокиДереваЗначенийНаФорме()
Для Каждого СтрокаДЗ Из Элементы.ДеревоЗначНаФорме.ВыделенныеСтроки Цикл
Элементы.ДеревоЗначНаФорме.Свернуть(СтрокаДЗ);
КонецЦикла;
КонецПроцедуры
💡 Шаблоны (готовые модели) кода 1С 8.3 с тегом #ДеревоЗначений:
📰 Актуальные новости с тегом #ДеревоЗначений:
- В версии 8.3.22 анонсирован дополнительный контроль заполнения значений в УФ. Проверка заполненности колонок дерева и таблицы значений
2
комментарии
Alenka-89
23 мар 2021
Разобралась. Возможно кому-то будет интересно, приведу свой пример заполнения реквизита формы Дерева Значений из Запроса в 1С 8.3:
&НаСервере
Процедура ДобавитьСтрокиПрограммноНаСервере()
ДеревоПомеченных = РеквизитФормыВЗначение("Дерево");
ДеревоПомеченных.Строки.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|Номенклатура.Ссылка КАК Наименование
|ИЗ
|Справочник.Номенклатура КАК Номенклатура
|
|УПОРЯДОЧИТЬ ПО
|Наименование ИЕРАРХИЯ";
ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ДеревоЗначений.Строки.Сортировать("Наименование Возв", Истина);
ЗначениеВРеквизитФормы(ДеревоЗначений, "Дерево");
КонецПроцедуры
&НаСервере
Процедура ДобавитьСтрокиПрограммноНаСервере()
ДеревоПомеченных = РеквизитФормыВЗначение("Дерево");
ДеревоПомеченных.Строки.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|Номенклатура.Ссылка КАК Наименование
|ИЗ
|Справочник.Номенклатура КАК Номенклатура
|
|УПОРЯДОЧИТЬ ПО
|Наименование ИЕРАРХИЯ";
ДеревоЗначений = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
ДеревоЗначений.Строки.Сортировать("Наименование Возв", Истина);
ЗначениеВРеквизитФормы(ДеревоЗначений, "Дерево");
КонецПроцедуры
Alenka-89
19 мар 2021
Доброго времени суток! Ругается на запрос: "нельзя использовать иерархическую сортировку в запросе с итогами > Наименование ИЕРАРХИЯ". Платформа 8.3 (8.3.16.1148). Каким должен быть запрос?
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник