Дерево значений 1С
Дерево значений 1С – это универсальная коллекция значений, в которой данные можно расположить в иерархическом порядке в виде дерева. По сути, дерево значений в 1С 8.3 — это таблица значений, где у строк могут быть подчиненные строки. Одна строка дерева значений может иметь несколько подчиненных строк, но в тоже время она может иметь только одну строку, которой подчинена, строку-родителя, или не иметь родителя вообще. Строка без родителя – это строка верхнего уровня, или первая строка.
В программном модуле дерево значений создается при помощи конструктора Новый.
ДеревоРегионов = Новый ДеревоЗначений;
Дерево значений, также как и таблица значений может работать только в серверном контексте или на толстом клиенте, на тонком клиенте с деревом значений можно работать только тогда, когда оно создано в виде реквизита управляемой формы 1С.
То есть, такой код, при выполнении на тонком клиенте, работать не будет:
&НаКлиенте Процедура СоздатьДерево(Команда) ДеревоРегионов = Новый ДеревоЗначений; КонецПроцедуры
Поэтому, желательно, деревья значений создавать в методах, которые работают в серверном контексте.
&НаСервере Процедура СоздатьДеревоНаСервере() ДеревоРегионов = Новый ДеревоЗначений; КонецПроцедуры &НаКлиенте Процедура СоздатьДерево(Команда) СоздатьДеревоНаСервере(); КонецПроцедуры
Колонки дерева значений 1С
Само по себе дерево значений не имеет смысла, для того, чтобы можно было с ним работать у этого дерева нужно создать колонки. Для этого, нужно использовать свойство дерева значений Колонки, которое имеет тип КоллекцияКолонокДереваЗначений, у объекта данного типа имеется ряд методов, с которыми вы можете познакомиться в синтакс-помощнике, а нас конкретно интересует метод Добавить. Этот метод добавляет новые колонки в дерево значений. Он имеет следующий синтаксис:
Где Имя – это имя колонки (уникальное в рамках этого дерева); Тип – в этом параметре описывают возможные типы колонки, делается при помощи объекта ОписаниеТипов; Заголовок – название колонки и Ширина — ширина колонки в символах.
Например, добавим нашему дереву регионов три колонки:
ТипСтрока = Новый ОписаниеТипов("Строка"); ТипЧисло = Новый ОписаниеТипов("Число"); ДеревоРегионов.Колонки.Добавить("Регион",ТипСтрока); ДеревоРегионов.Колонки.Добавить("РуководительРегиона",ТипСтрока,"Руководитель региона"); ДеревоРегионов.Колонки.Добавить("Бюджет",ТипЧисло);
Мы добавили три колонки, две из которых имеют тип строка, а одна имеет тип число.
Строки дерева значений 1С
Строки дерева значений 1С бывают двух видов. Это строки верхнего (или первого) уровня. Те строки, у которых нет ни каких родителей, и которые ни кому не подчинены. И подчиненные строки – это строки более низких уровней. У подчиненных строк заполнено свойство Родитель, в котором указывается родительская строка, т.е. та строка, которой подчинена эта текущая строка (у строк верхнего уровня свойство Родитель пустое). Для того, чтобы создать строку верхнего (или первого) уровня, нужно воспользоваться свойством Строки дерева значений. Это свойство имеет тип КоллекцияСтрокДереваЗначений. И у объекта этого типа есть метод Добавить, который создает новую строку верхнего (первого) уровня. Причем, этот метод является функцией, которая возвращает строку дерева значений. А у этой строки мы, как к свойствам, можем обращаться к колонкам дерева значений.
СтрокаВерхнего = ДеревоРегионов.Строки.Добавить(); СтрокаВерхнего.Регион = "Приволжский округ"; СтрокаВерхнего.РуководительРегиона = "Петров"; СтрокаВерхнего.Бюджет = 1000000; СтрокаВерхнего = ДеревоРегионов.Строки.Добавить(); СтрокаВерхнего.Регион = "Сибирский округ"; СтрокаВерхнего.РуководительРегиона = "Борисов"; СтрокаВерхнего.Бюджет = 1000000;
В этом коде добавлено две строки верхнего уровня дерева регионов.
Для того, чтобы добавить строку следующего уровня (второго, третьего и т.д.) нужно воспользоваться свойством Строки уже созданной строки.
Например, так мы создаем две строки второго уровня:
СтрокаВторогоОдин = СтрокаВерхнего.Строки.Добавить(); СтрокаВторогоОдин.Регион = "Удмуртия"; СтрокаВторогоОдин.РуководительРегиона = "Бречалов"; СтрокаВторогоОдин.Бюджет = 500000; СтрокаВторогоДва = СтрокаВерхнего.Строки.Добавить(); СтрокаВторогоДва.Регион = "Татарстан"; СтрокаВторогоДва.РуководительРегиона = "Шаймиев"; СтрокаВторогоДва.Бюджет = 500000;
А так, мы создаем строки третьего уровня (две для Удмуртии и одну для Татарстана):
СтрокаТретьегоОдин = СтрокаВторогоОдин.Строки.Добавить(); СтрокаТретьегоОдин.Регион = "Завьяловский район"; СтрокаТретьегоОдин.РуководительРегиона = "Иванов"; СтрокаТретьегоОдин.Бюджет = 100000; СтрокаТретьегоДва = СтрокаВторогоОдин.Строки.Добавить(); СтрокаТретьегоДва.Регион = "Ярский район"; СтрокаТретьегоДва.РуководительРегиона = "Сидоров"; СтрокаТретьегоДва.Бюджет = 100000; СтрокаТретьегоТри = СтрокаВторогоДва.Строки.Добавить(); СтрокаТретьегоТри.Регион = "Мензилинский район"; СтрокаТретьегоТри.РуководительРегиона = "Шайхметов"; СтрокаТретьегоТри.Бюджет = 100000;
Обход дерева значений 1С
Для обхода дерева значений необходимо обращаться к свойству Строки или самого дерева, или строки дерева значений. Так мы обходим строки первого или верхнего уровня:
Для Каждого СтрПервогоУровня из ДеревоРегионов.Строки Цикл Сообщить(СтрПервогоУровня.Регион + "/" + СтрПервогоУровня.Руководитель); КонецЦикла;
Поскольку свойство Строки дерева значений является коллекцией, то к ней применим цикл Для Каждого Цикл. Где в значении очередного элемента коллекции находится строка верхнего уровня (первого) дерева значений, у этой строки можно обращаться к колонкам как к свойствам.
Если нам нужно обойти строку следующего уровня, то в этот раз следует уже циклом Для каждого Цикл обходить свойство Строки текущей строки дерева значений.
Для Каждого СтрПервогоУровня из ДеревоРегионов.Строки Цикл Сообщить(СтрПервогоУровня.Регион + "/" + СтрПервогоУровня.Руководитель); Для Каждого стрВторогоУровня из СтрПервогоУровня.Строки Цикл Сообщить(стрВторогоУровня.Регион + "/" + стрВторогоУровня.Руководитель); КонецЦикла; КонецЦикла;
Проблема в том, что мы не можем знать настоящую вложенность дерева значений 1С, поэтому для обхода деревьев лучше применять рекурсивный вызов метода.
&НаСервере Процедура ВывестиДерево(СтрокиДерева) Для Каждого стрДерева из СтрокиДерева Цикл Сообщить(стрДерева.Регион + "/" + стрДерева.РуководительРегиона + "/"); Если стрДерева.Строки.Количество() > 0 Тогда ВывестиДерево(стрДерева.Строки); КонецЕсли; КонецЦикла; КонецПроцедуры
Например, в этой процедуры мы обходим строки дерева, и если у строки дерева имеются подчиненные строки, то мы вызываем опять эту же процедуру, где в качестве параметра указываем подчиненные строки.
Теперь нам достаточно эту процедуру вызвать в том месте, где мы создаем и заполняем дерево.
ВывестиДерево(ДеревоРегионов.Строки);
Ну и для того, чтобы наш список выглядел более наглядно, будем при выводе строк второго и третьего уровня добавлять тире. Для этого создадим функцию, которая добавляет тире, количество которых зависит от уровня вложенности. А узнать уровень вложенности строки можно при помощи метода строки дерева значений Уровень(), который возвращает уровень вложенности строки начиная с 0.
&НаСервере Процедура ВывестиДерево(СтрокиДерева) Для Каждого стрДерева из СтрокиДерева Цикл Пробелы = СформироватьТире(стрДерева.Уровень()); Сообщить(Пробелы + стрДерева.Регион + "/" + стрДерева.РуководительРегиона + "/"); Если стрДерева.Строки.Количество() > 0 Тогда ВывестиДерево(стрДерева.Строки); КонецЕсли; КонецЦикла; КонецПроцедуры Функция СформироватьТире(Уровень) Если Уровень = 0 Тогда Возврат ""; КонецЕсли; Пробелы = ""; Для н = 1 по Уровень Цикл Пробелы = Пробелы + " - "; КонецЦикла; Возврат Пробелы; КонецФункции

Дерево значений 1С на управляемой форме
Для того, чтобы на управляемой форме создать дерево значений, нужно добавить реквизит на управляемую форму и присвоить тип этому реквизиту ДеревоЗначений.

Само по себе такое дерево бессмысленно. Нужно добавить ему колонки. Если мы хотим дереву значений на форме добавить колонку, то необходимо сначала выделить дерево на форме, а потом нажать на кнопку «Добавить колонку реквизита».

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

В моей учебной конфигурации имеется справочник Регионы, который является иерархическим (иерархия элементов).

Сделаем так, чтобы созданное дерево на форме заполнялось информацией из этого справочника. Для этого, на форме создадим обработчик ПриСозданииНаСервере, и в этом обработчике запросом получим информацию из справочника в иерархическом виде.
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Регионы.Ссылка КАК Регион, | Регионы.ВидРегиона КАК ВидРегиона |ИЗ | Справочник.Регионы КАК Регионы | |УПОРЯДОЧИТЬ ПО | Регионы.Ссылка ИЕРАРХИЯ"; КонецПроцедуры
Заполнить это дерево можно несколькими способами. В первом способе, мы в рекурсивной процедуре обходим выборку из запроса, и если у этой выборки имеется выборка вложенных записей, то вызываем эту же процедуру.
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Регионы.Ссылка КАК Регион, | Регионы.ВидРегиона КАК ВидРегиона |ИЗ | Справочник.Регионы КАК Регионы | |УПОРЯДОЧИТЬ ПО | Регионы.Ссылка ИЕРАРХИЯ"; ОписаниеРегиона = Новый ОписаниеТипов("СправочникСсылка.Регионы"); ОписаниеВидаРегиона = Новый ОписаниеТипов("ПеречислениеСсылка.ВидРегиона"); Дерево = Новый ДеревоЗначений; Дерево.Колонки.Добавить("Регион",ОписаниеРегиона); Дерево.Колонки.Добавить("ВидРегиона",ОписаниеВидаРегиона); Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией); ЗаполнитьДерево(Дерево.Строки, Выборка); ЗначениеВРеквизитФормы(Дерево,"ДеревоЗначений"); КонецПроцедуры &НаСервере Процедура ЗаполнитьДерево(СтрокиДерева, Выборка) Пока Выборка.Следующий() Цикл НовСтрока = СтрокиДерева.Добавить(); НовСтрока.Регион = Выборка.Регион; НовСтрока.ВидРегиона = Выборка.ВидРегиона; ВыборкаПодчиненная = Выборка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией); Если ВыборкаПодчиненная.Количество() > 0 Тогда ЗаполнитьДерево(НовСтрока.Строки,ВыборкаПодчиненная); КонецЕсли; КонецЦикла; КонецПроцедуры
Второй способ проще в плане набора кода, но он неоптимальный с точки зрения производительности: мы просто получим выгрузку из запроса и загрузим выгрузку в дерево значений на форме.
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Регионы.Ссылка КАК Регион, | Регионы.ВидРегиона КАК ВидРегиона |ИЗ | Справочник.Регионы КАК Регионы | |УПОРЯДОЧИТЬ ПО | Регионы.Ссылка ИЕРАРХИЯ"; Дерево = Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией); ЗначениеВРеквизитФормы(Дерево,"ДеревоЗначений"); КонецПроцедуры
Как в результате первого способа и второго, у нас будет заполнена дерево значений на управляемой форме.

Также с деревом значений на форме можно работать напрямую. Дерево значений на управляемой форме конвертируется в объект ДанныеФормыДерево, который моделирует работу дерева на управляемой форме. Для того, чтобы обратиться к элементам верхнего уровня этого объекта нам необходимо воспользоваться методом ПолучитьЭлементы(), который возвращает объект имеющий тип ДанныеФормыКоллекцияЭлементовДерева, этот тип является коллекцией, и как любую коллекцию его можно обойти циклом и получить элемент этой коллекции, а уже у элемента этой коллекции посредством метода ПолучитьЭлементы() можно получить подчиненные ему строки и т.д.
Например, сделаем чистку колонки ВидРегиона созданного ранее дерева, для этого создадим рекурсивную процедуру, в которой будем обходить элементы дерева с формы, очищать колонку, а если, у обходимого элемента имеются подчиненные ему элементы, то опять вызывать эту процедуру.
&НаКлиенте Процедура ОбойтиИОчиститьДеревоНаФорме(ЭлементыДерева) Для Каждого стрДерева из ЭлементыДерева Цикл стрДерева.ВидРегиона = ПредопределенноеЗначение("Перечисление.ВидРегиона.ПустаяСсылка"); ПодСтроки = стрДерева.ПолучитьЭлементы(); Если ПодСтроки.Количество() > 0 Тогда ОбойтиИОчиститьДеревоНаФорме(ПодСтроки); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Процедура Очистить(Команда) ОбойтиИОчиститьДеревоНаФорме(Регионы.ПолучитьЭлементы()); КонецПроцедуры

Статьи о других универсальных коллекциях значений в 1С
Более подробно о работе с другими интересными объектами языка программирования в 1С читайте в моей книге «Программировать в 1С за 11 шагов»

Изучайте программирование в 1С в месте с моей книги «Программировать в 1С за 11 шагов»
- Книга написана понятным и простым языком — для новичка.
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Научитесь понимать архитектуру 1С;
- Станете писать код на языке 1С;
- Освоите основные приемы программирования;
- Закрепите полученные знания при помощи задачника;

Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.
- Очень доступный и понятный язык изложения
- Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
- Поймете идеологию управляемого приложения 1С
- Узнаете, как разрабатывать управляемое приложение;
- Научитесь разрабатывать управляемые формы 1С;
- Сможете работать с основными и нужными элементами управляемых форм
- Программирование под управляемым приложением станет понятным
Промо-код на скидку в 15% — 48PVXHeYu
Если Вам помог этот урок решить какую-нибудь проблему, понравился или оказался полезен, то Вы можете поддержать мой проект, перечислив любую сумму:
можно оплатить вручную:
Вступайте в мои группы:
Дерево значений 1с. Описание и примеры использования
ДеревоЗначений — это программный объект встроенного языка, позволяющий строить произвольные иерархические наборы данных в памяти компьютера, отображать их в табличном и\или древовидном виде, а также программно и интерактивно манипулировать ими (добавлять, редактировать, удалять и сортировать строки).
Как и таблица значений, дерево состоит из строк и колонок. Строки располагаются вниз по вертикали, а колонки — вправо по горизонтали. Однако, в отличие от таблицы значений, строки дерева значений могут иметь подчиненные строки любой глубины вложенности.
Строки и колонки имеют индексы, по которым к ним можно обращаться напрямую (начинаются с 0). Кроме этого, к колонкам можно обращаться по идентификатору.

Пересечения строк и колонок образуют ячейки, в которых содержатся значения. Тип значения определяется типом значения колонки.
Дерево значений является полностью динамическим объектом, т.е. Вы можете манипулировать не только строками дерева, добавляя и удаляя их, но и колонками.
Дерево значений может использоваться явно при создании в коде необходимого количества переменных типа ДеревоЗначений , либо неявно: при добавлении элемента управления ТабличноеПоле на обычную форму, и ТаблицаФормы — на управляемую. Здесь мы рассмотрим только программную работу с деревом значений.
Создание дерева значений
Как и большинство объектов встроенного языка, новая дерево значений может быть создано с помощью оператора Новый :
дз = Новый ДеревоЗначений;
Свойства и методы дерева значений
| Имя | Тип | Описание |
|---|---|---|
| Свойства | ||
| Колонки | КоллекцияКолонокДереваЗначений | содержит коллекцию колонок дерева значений |
| Строки | КоллекцияСтрокДереваЗначений | содержит коллекцию корневых строк дерева значений |
| Методы | ||
| ВыбратьСтроку() | СтрокаДереваЗначений | открывает диалог для интерактивного выбора строки дерева значений |
| Скопировать() | ДеревоЗначений | создает новый объект копированием текущего (копируются все колонки и строки) |
Колонки дерева значений
Прежде чем начать работу с деревом значений, необходимо создать структуру колонок. Каждая колонка характеризуется следующими свойствами:
| Имя | Тип | Описание |
|---|---|---|
| Имя | Строка | символьный идентификатор колонки, по которому к ней можно обращаться из кода. Может содержать только алфавитные символы, цифры и знаки подчеркивания. Причем, начинаться имя колонки может только с буквы или символа подчеркивания |
| Заголовок | Строка | строковое представление колонки на форме. Может содержать произвольные символы |
| ТипЗначения | ОписаниеТипов | тип значения содержимого ячеек в этой колонке. Свойство ограничивает пространство доступных значений, которые можно указать в данной колонке |
| Ширина | Число | ширина колонки на форме (выражается в количестве символов) |
Доступ к колонкам производится через свойство Колонки объекта ДеревоЗначений . Для добавления новой колонки используется метод Колонки.Добавить():
дз.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка")); дз.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число")); дз.Колонки.Добавить("Свойство");//можно хранить произвольные данные
Для того, чтобы определить наличие колонки с нужным именем используется метод Колонки.Найти():
найдКолонка = дз.Колонки.Найти("Наименование"); Если найдКолонка = Неопределено Тогда Сообщить("Колонка не найдена!"); Иначе Сообщить("Индекс колонки color: red;">+ дз.Колонки.Индекс(найдКолонка)); КонецЕсли;
Перебор колонок выполняется следующим образом:
Для каждого Колонка Из дз.Колонки Цикл Сообщить(Колонка.Имя + ": " + Колонка.ТипЗначения); КонецЦикла; //Результат: // Наименование: Строка // Количество: Число // Свойство:
Для удаления колонки используется метод Колонки.Удалить():
найдКолонка = дз.Колонки.Найти("Свойство"); Если НЕ найдКолонка = Неопределено Тогда дз.Колонки.Удалить(найдКолонка); КонецЕсли;
Методы коллекции колонок дерева значений
| Вставить() | Вставляет новую колонку в указанную позицию коллекции |
| Добавить() | Добавляет новую колонку в конец коллекции |
| Индекс() | Возвращает индекс колонки в коллекции колонок |
| Получить() | Возвращает колонку по ее индексу |
| Количество() | Возвращает количество колонок в коллекции |
| Найти() | Ищет колонку в коллекции по имени |
| Очистить() | Удаляет все колонки из коллекции |
| Сдвинуть() | Сдвигает колонку влево или вправо |
| Удалить() | Удаляет колонку из коллекции |
Строки дерева значений
С колонками разобрались. Давайте теперь разберемся со строками. Строки дерева значений можно программно добавлять и удалять, перемещать и сортировать, а также выполнять операции поиска и отбора.
В отличие от таблицы значений, доступ к строкам дерева значений производится через свойство Строки объекта ДеревоЗначений или объекта СтрокаДереваЗначений . Каждая строка является узлом иерархии, поэтому обладает следующими свойствами и методами:
| Имя | Тип | Описание |
|---|---|---|
| Свойства | ||
| Родитель | СтрокаДереваЗначений | ссылается на строку верхнего уровня. Для корневой строки имеет значение Неопределено |
| Строки | КоллекцияСтрокДереваЗначений | содержит коллекцию подчиненных строк |
| Методы | ||
| Владелец() | ДеревоЗначений | возвращает ссылку на дерево значений, которому принадлежит строка |
| Уровень() | Число | возвращает уровень вложенности строки в иерархии дерева. Для строки, не имеющей родителя, уровень будет равен 0 (верхний уровень или корневой уровень). Подчиненная ей строка будет иметь уровень 1 и т.д. |
Добавление и удаление строк
Для добавления новой строки используется метод Строки.Добавить(). Метод возвращает объект СтрокаДереваЗначений , с которым доступны дальнейшие манипуляции:
СтрокаДЗ = дз.Строки.Добавить();
И только теперь мы можем заполнить строку данными. Для этого обращаемся к ячейкам строки, указывая идентификаторы колонок через точку:
СтрокаДЗ.Наименование = "Стул деревянный"; СтрокаДЗ.Количество = 1; СтрокаДЗ.Свойство = ТекущаяДата();
Для удаления строки используется метод Строки.Удалить(). Строку можно удалить передав методу либо саму строку, либо ее индекс:
//удаление строки дз.Строки.Удалить(СтрокаДЗ); //удаление по индексу ИндексСтроки = дз.Строки.Индекс(СтрокаДЗ); дз.Строки.Удалить(ИндексСтроки); //безопасное удаление НайдСтрока = дз.Строки.Найти("Стул деревянный", "Наименование"); Если НЕ НайдСтрока = Неопределено Тогда дз.Строки.Удалить(НайдСтрока); КонецЕсли;
Перебор строк дерева значений
Для перебора строк удобнее всего использовать оператор цикла Для Каждого . В редких случаях оправдано применение цикла Для :
Для Каждого СтрокаДЗ Из дз.Строки Цикл ИндСтроки = дз.Строки.Индекс(СтрокаДЗ); Сообщить("Строка[" + ИндСтроки + "]: " + СтрокаДЗ.Наименование); КонецЦикла; //в редких случаях Для ИндСтроки = 0 По дз.Строки.Количество() - 1 Цикл СтрокаДЗ = дз.Строки.Получить(ИндСтроки); Сообщить("Строка[" + ИндСтроки + "]: " + СтрокаДЗ.Наименование); КонецЦикла;
Поиск строк
Поиск в дереве значений можно выполнять не только по значению в колонке (в этом случае будет возвращена первая найденная строка), но и по набору свойств (в этом случае возвращается массив строк).
//удаление первой найденной строки НайдСтрока = дз.Строки.Найти("Стул деревянный", "Наименование"); Если НЕ НайдСтрока = Неопределено Тогда дз.Строки.Удалить(НайдСтрока); КонецЕсли; //удаление всех найденных строк ПараметрыПоиска = Новый Структура("Наименование", "Стул деревянный"); мНайдСтроки = дз.Строки.НайтиСтроки(ПараметрыПоиска); Для каждого НайдСтрока Из мНайдСтроки Цикл дз.Строки.Удалить(НайдСтрока); КонецЦикла;
Поиск возможен даже среди вложенных строк. Внимательно изучите документацию к методам Строки.Найти() и Строки.НайтиСтроки().
Все методы коллекции строк дерева значений:
| Вставить() | Вставляет строку на указанное место коллекции строк |
| ВыгрузитьКолонку() | Выгружает значения ячеек указанной колонки из текущей коллекции строк в массив значений |
| Добавить() | Добавляет новую строку в коллекцию строк |
| ЗагрузитьКолонку() | Загружает значения из массива в ячейки указанной колонки коллекции строк |
| Индекс() | Возвращает индекс строки дерева значений в коллекции |
| Итог() | Возвращает просуммированный итог по колонке дерева значений |
| Количество() | Возвращает количество строк в коллекции строк |
| Найти() | Выполняет поиск строки по значению |
| НайтиСтроки() | Выполняет поиск строк по указанным параметрам |
| Очистить() | Удаляет все строки из текущей коллекции строк |
| Получить() | Возвращает строку по ее индексу |
| Сдвинуть() | Сдвигает строку вверх или вниз по коллекции строк |
| Сортировать() | Выполняет сортировку строк в коллекции по указанным колонкам |
| Удалить() | Удаляет строку из коллекции строк |
Иерархию свойств и типов значений, связанных с деревом значений, схематически можно представить в виде дерева:
1С 8.3 Дерево значений — Программист 1С Минск. Автоматизация бизнеса.

ПРИМЕРЫ КОДА 1С
Дерево Значений в 1С 8.3 — это иерархический динамически набор любого типа. По своим функциям и структуре (колонки и строки) очень схожа с Таблицей Значений, но есть виртуальная колонка «Родитель». Дерево значений рекомендуется использовать для работы именно с иерархической информацией . Каждая строка дерева значений имеет свойства «Родитель» и «Строки», а также может иметь любое количество подчиненных строк. Операции с помощью встроенного функционала (сортировка, раскраска строк, поиск, итоги, различные отборы ) могут производится с учетом подчиненных строк / уровней иерархии.
Оглавление:

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

Рассмотрим задачу, когда на форме нужно заполнить элемент дерева значений.
Рассмотрим на примере заполнения элемента ДеревоЦен формы документа Установка цен номенклатуры конфигурации УТ 11.0.7.21. В элемент ДеревоЦен записываются данные по номенклатуре, а в подчиненные номенклатуре строки – данные по характеристикам номенклатуры. В результате в табличной части Товары документа Установка цен номенклатуры находятся строки по Номенклатуре (без характеристики) и строки по Характеристикам номенклатуры (т.е. получается как развернутый вид дерева значений ДеревоЦен).

В рассматриваемом примере на форму документа добавлена команда пр_ЗаполнитьДеревоЦен. В процедуре описания действия команды вызывается процедура пр_ЗаполнитьДеревоЦенСервер(). Элемент ДеревоЦен заполняется товарами из ассортимента выбранного партнера, для этого в конфигурацию добавлен регистр сведений пр_АссортиментТоваров с измерениями Партнер и Характеристика; в документ Установка цен номенклатуры добавлен реквизит пр_Партнер.
Пример процедуры для заполнения элемента ДеревоЦен:
&НаСервере Процедура пр_ЗаполнитьДеревоЦенСервер() Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | пр_АссортиментТоваров.Характеристика КАК Характеристика, | пр_АссортиментТоваров.Характеристика.Владелец КАК Номенклатура, | пр_АссортиментТоваров.Характеристика.Владелец.ЕдиницаИзмерения КАК ЕдиницаИзмерения, | пр_АссортиментТоваров.Характеристика.Владелец.ЦеноваяГруппа КАК ЦеноваяГруппа, | пр_АссортиментТоваров.Характеристика.Владелец.ВидНоменклатуры.ИспользованиеХарактеристик КАК ИспользованиеХарактеристик |ИЗ | РегистрСведений.пр_АссортиментТоваров КАК пр_АссортиментТоваров |ГДЕ | пр_АссортиментТоваров.Партнер = &Партнер |ИТОГИ | МАКСИМУМ(Характеристика), | МАКСИМУМ(ЕдиницаИзмерения), | МАКСИМУМ(ЦеноваяГруппа), | МАКСИМУМ(ИспользованиеХарактеристик) |ПО | Номенклатура"; Запрос.УстановитьПараметр("Партнер", Объект.пр_Партнер); РезультатПоНоменклатуре = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам); ДеревоЦенДЗ = РеквизитФормыВЗначение("ДеревоЦен", Тип("ДеревоЗначений")); Пока РезультатПоНоменклатуре.Следующий() Цикл СтрокаДерева = ДеревоЦенДЗ.Строки.Добавить(); СтрокаДерева.Номенклатура = РезультатПоНоменклатуре.Номенклатура; //СтрокаДерева.Характеристика = Результат.Характеристика; СтрокаДерева.ЕдиницаИзмерения = РезультатПоНоменклатуре.ЕдиницаИзмерения; СтрокаДерева.ЦеноваяГруппа = РезультатПоНоменклатуре.ЦеноваяГруппа; Если РезультатПоНоменклатуре.ИспользованиеХарактеристик = Перечисления.ВариантыВеденияДополнительныхДанныхПоНоменклатуре.НеИспользовать Тогда СтрокаДерева.ХарактеристикиИспользуются = Ложь; Иначе СтрокаДерева.ХарактеристикиИспользуются = Истина; КонецЕсли; РезультатПоХарактеристикам = РезультатПоНоменклатуре.Выбрать(); Пока РезультатПоХарактеристикам.Следующий() Цикл ПодСтрокаДерева = СтрокаДерева.Строки.Добавить(); ПодСтрокаДерева.Номенклатура = РезультатПоХарактеристикам.Номенклатура; ПодСтрокаДерева.Характеристика = РезультатПоХарактеристикам.Характеристика; ПодСтрокаДерева.ЕдиницаИзмерения = РезультатПоХарактеристикам.ЕдиницаИзмерения; ПодСтрокаДерева.ЦеноваяГруппа = РезультатПоХарактеристикам.ЦеноваяГруппа; Если РезультатПоХарактеристикам.ИспользованиеХарактеристик = Перечисления.ВариантыВеденияДополнительныхДанныхПоНоменклатуре.НеИспользовать Тогда ПодСтрокаДерева.ХарактеристикиИспользуются = Ложь; Иначе ПодСтрокаДерева.ХарактеристикиИспользуются = Истина; КонецЕсли; КонецЦикла; КонецЦикла; ЗначениеВРеквизитФормы(ДеревоЦенДЗ,"ДеревоЦен"); КонецПроцедуры
