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

Apr 03, 2022 14:31

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

Поиск, сортировка и получение итогов могут выполняться как только по одному уровню иерархии, так и включая подчиненные строки.

В толстом клиенте нельзя передавать дерево значений с клиента на сервер. На тонком клиенте дерево значений не доступно.

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

Создать новое дерево значений можно с помощью конструктора:

//создание дерева без колонок и строк
ДеревоТоваров = Новый ДеревоЗначений;

У дерева значений есть свойства Колонки и Строки. Для добавления новых строк сначала нужно добавить колонки дерева:


//добавление колонок в дерево значений
ДеревоТоваров.Колонки.Добавить("Номенклатура");
ДеревоТоваров.Колонки.Добавить("Цена");

Теперь через свойство Строки можно добавлять строки дерева:

//добавление новых строк
СтрДерева = ДеревоТоваров.Строки.Добавить();
СтрДерева.Номенклатура = "Монитор";
СтрДерева.Цена = 10000;

СтрДерева= ДеревоТоваров.Строки.Добавить();
СтрДерева.Номенклатура = "Системный блок";
СтрДерева.Цена = 30000;

Новые строки будут добавлены на первый уровень иерархии. Чтобы добавить к существующей строке подчиненные строки нужно обратиться к свойству Строки существующей строки дерева значений:

ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Номенклатура = "Процессор";
ПодчиненнаяСтрока.Цена = 10000;

ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Номенклатура = "Оперативная память";
ПодчиненнаяСтрока.Цена = 5000;

В результате у строки с номенклатурой «Системный блок» будет 2 подчиненных строки с процессором и оперативной памятью.

Рассмотрим другие операции с деревом значений:

//вставить новую строку в самое начало
СтрДерева = ДеревоТоваров.Строки.Вставить(0); //указываем индекс строки,
//куда ее нужно вставить
СтрДерева.Номенклатура = "Клавиатура";
СтрДерева.Цена = 1000;

//к строкам можно обращаться через квадратные скобки
//в квадратных скобках указывается индекс строки
Сообщить(ДеревоТоваров.Строки[1].Номенклатура); //Монитор

//через квадратные скобки можно обращаться к колонкам дерева через имя колонки
СтрДерева["Цена"] = 1500; //теперь Клавиатура стоит 1500

//можно через методы Установить и Получить
СтрДерева.Установить(1, 2000); //первым параметром передается индекс колонки
Сообщить(СтрДерева.Получить(1)); //2000

//с помощью метода Владелец из строки можно получить само дерево
СсылкаНаДерево = СтрДерева.Владелец(); //получаем само дерево

//через свойство Родитель у подчиненной строки можно получить родительскую строку
РодСтрока = ПодчиненнаяСтрока.Родитель;
Сообщить(РодСтрока.Номенклатура); // Монитор

Колонки дерева значений

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

ДеревоЗаказов = Новый ДеревоЗначений;
//добавление новой колонки дерева значений
ДеревоЗаказов.Колонки.Добавить("Заказ");

//добавление типизированной колонки
ДеревоЗаказов.Колонки.Добавить("СуммаЗаказа", Новый ОписаниеТипов("Число"));

//проверка есть ли такая колонка
НайдКолДер = ДеревоЗаказов.Колонки.Найти("Заказ");
Если НайдКолДер = Неопределено Тогда
//нет такой колонки
Иначе
//НайдКолДер- ссылка на колонку дерева
КонецЕсли;

//количество колонок
Колво = ДеревоЗаказов.Колонки.Количество();

//перебор всех колонок
Для Каждого КолДер Из ДеревоЗаказов.Колонки Цикл
//у колонки есть свойства Имя, ТипЗначения, Заголовок и Ширина
Сообщить(КолДер.Имя);
Сообщить(КолДер.ТипЗначения);
Сообщить(КолДер.Заголовок);
Сообщить(КолДер.Ширина);
//Заголовок и Ширина используются если дерево отображается на форме
КонецЦикла;

//удаление одной колонки
ДеревоЗаказов.Колонки.Удалить(0); //удаляем первую строку

//удаление всех колонок
ДеревоЗаказов.Колонки.Очистить();

Итоги по дереву значений

Для получения итога по числовой колонке дерева значений можно использовать метод Итог:

ДеревоСумм = Новый ДеревоЗначений;
ДеревоСумм.Колонки.Добавить("Сумма");

//добавим 2 строки на первый уровень
СтрДерева = ДеревоСумм.Строки.Добавить();
СтрДерева.Сумма = 100;

СтрДерева = ДеревоСумм.Строки.Добавить();
СтрДерева.Сумма = 200;

//и 2 подчиненные строки у второй строки
ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Сумма = 50;

ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Сумма = 60;

//получим итог по строкам первого уровня
Сообщить(ДеревоСумм.Строки.Итог("Сумма", Ложь)); //300

//чтобы получить итог по всем строкам, включая подчиненные
//нужно вторым параметром передать Истина
Сообщить(ДеревоСумм.Строки.Итог("Сумма", Истина)); //410

Поиск по дереву значений

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

ДеревоТоваров = Новый ДеревоЗначений;
ДеревоТоваров.Колонки.Добавить("Товар");

//добавим 3 строки на первый уровень
СтрДерева = ДеревоТоваров.Строки.Добавить();
СтрДерева.Товар = "Монитор";

СтрДерева = ДеревоТоваров.Строки.Добавить();
СтрДерева.Товар = "Монитор";

СтрДерева = ДеревоТоваров.Строки.Добавить();
СтрДерева.Товар = "Системный блок";

//и 2 подчиненные строки у третьей строки
ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Товар = "Процессор";

ПодчиненнаяСтрока = СтрДерева.Строки.Добавить();
ПодчиненнаяСтрока.Товар = "Диск";

//первый параметр значение поиска
//второй - колонка дерева для поиска
НайдСтр = ДеревоТоваров.Строки.Найти("Монитор", "Товар", Ложь);
//вернет первую строку

НайдСтр = ДеревоТоваров.Строки.Найти("Диск", "Товар", Ложь);
//вернет Неопределено, строка не найдена

НайдСтр = ДеревоТоваров.Строки.Найти("Диск", "Товар", Истина);
//вернет подчиненную строку

//параметром передается структура
//ключ - колонка дерева для поиска
//значение - значение поиска
//можно указать несколько ключей, поиск будет выполняться по всем совпадениям
Отбор = Новый Структура("Товар", "Монитор");
НС = ДеревоТоваров.Строки.НайтиСтроки(Отбор, Ложь);
//вернет массив с двумя строками

Отбор = Новый Структура("Товар", "Диск");
НС = ДеревоТоваров.Строки.НайтиСтроки(Отбор, Ложь);
//вернет пустой массив

НС = ДеревоТоваров.Строки.НайтиСтроки(Отбор, Истина);
//вернет массив с одной подчиненной строкой

Удаление строк из дерева значений

Для удаления строк из дерева значений используются методы Удалить и Очистить. Метод Удалить удаляет строку, включая все подчиненные ей строки. Метод Очистить удаляет все строки из дерева значений.

ДеревоТоваров = Новый ДеревоЗначений;
ДеревоТоваров.Колонки.Добавить("Товар");

//добавим 3 строки на первый уровень
ПерваяСтрока = ДеревоТоваров.Строки.Добавить();
ПерваяСтрока.Товар = "Монитор";

ВтораяСтрока = ДеревоТоваров.Строки.Добавить();
ВтораяСтрока.Товар = "Монитор";

ТретьяСтрока = ДеревоТоваров.Строки.Добавить();
ТретьяСтрока.Товар = "Системный блок";

//и 2 подчиненные строки у третьей строки
ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Товар = "Процессор";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Товар = "Диск";

//удалим строку с системным блоком:
ДеревоТоваров.Строки.Удалить(ТретьяСтрока);

//удалим строку с первым монитором по индексу
ДеревоТоваров.Строки.Удалить(0);

//удалим все строки дерева
ДеревоТоваров.Строки.Очистить();

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

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

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

ДеревоТоваров = Новый ДеревоЗначений;
ДеревоТоваров.Колонки.Добавить("Количество");

//добавим 3 строки на первый уровень
ПерваяСтрока = ДеревоТоваров.Строки.Добавить();
ПерваяСтрока.Количество = "2";

ВтораяСтрока = ДеревоТоваров.Строки.Добавить();
ВтораяСтрока.Количество = "1";

ТретьяСтрока = ДеревоТоваров.Строки.Добавить();
ТретьяСтрока.Количество = "3";

//и 3 подчиненные строки у третьей строки
ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "20";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "10";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "30";

//отсортируем по возрастанию
ДеревоТоваров.Строки.Сортировать("Количество", Ложь);
//так как второй параметр равен Ложь, то подчиненные строки
//не были отсортированы

//отсортируем по убыванию, включая подчиненные строки
//чтобы отсортировать по убыванию нужно после имени колонки указать Убыв
ДеревоТоваров.Строки.Сортировать("Количество Убыв", Истина);

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

Для создания полной копии дерева значений можно воспользоваться методом Скопировать.

ДеревоТоваров = Новый ДеревоЗначений;
ДеревоТоваров.Колонки.Добавить("Количество");

//добавим 3 строки на первый уровень
ПерваяСтрока = ДеревоТоваров.Строки.Добавить();
ПерваяСтрока.Количество = "2";

ВтораяСтрока = ДеревоТоваров.Строки.Добавить();
ВтораяСтрока.Количество = "1";

ТретьяСтрока = ДеревоТоваров.Строки.Добавить();
ТретьяСтрока.Количество = "3";

//и 3 подчиненные строки у третьей строки
ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "20";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "10";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "30";

// создание полной копии дерева, со всеми строками и колонками
КопияДерева = ДеревоТоваров.Скопировать();

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

Рекурсивный обход дерева значений

Обойти дерево значений можно с помощью цикла Для Каждого. Если нужно обойти все дерево, включая подчиненные строки, то можно использовать рекурсию:

&НаСервере
Процедура Команда1НаСервере()

ДеревоТоваров = Новый ДеревоЗначений;
ДеревоТоваров.Колонки.Добавить("Количество");

//добавим 3 строки на первый уровень
ПерваяСтрока = ДеревоТоваров.Строки.Добавить();
ПерваяСтрока.Количество = "2";

ВтораяСтрока = ДеревоТоваров.Строки.Добавить();
ВтораяСтрока.Количество = "1";

ТретьяСтрока = ДеревоТоваров.Строки.Добавить();
ТретьяСтрока.Количество = "3";

//и 3 подчиненные строки у третьей строки
ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "20";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "10";

ПодчиненнаяСтрока = ТретьяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Количество = "30";

//обход только строк верхнего уровня
Для Каждого СтрДер Из ДеревоТоваров.Строки Цикл
Сообщить(СтрДер.Количество);
КонецЦикла;

//обход всего дерева значений
РекурсивныйОбходДереваЗначений(ДеревоТоваров);
КонецПроцедуры

&НаСервере
Процедура РекурсивныйОбходДереваЗначений(ДеревоЗначенийИлиСтрокаДерева)
Для Каждого СтрДер Из ДеревоЗначенийИлиСтрокаДерева.Строки Цикл
Сообщить(СтрДер.Количество);
//передаем строку дерева в эту же процедуру
//чтобы обойти все ее подчиненные строки
РекурсивныйОбходДереваЗначений(СтрДер);
КонецЦикла;
КонецПроцедуры

Смотрите также:
Электронный учебник по по программированию в 1С
Рекомендации по изучению программирования 1С с нуля
Программное решение для сдачи и подготовки к экзаменам
Программирование в 1С 8.3 с нуля - краткий самоучитель
Комплексная подготовка программистов 1С:Предприятие 8.2
Сайты с уроками программирования и со справочниками
Youtube-каналы с уроками программирования
Сайты для обучения программированию
Лекции и уроки

программирование

Previous post Next post
Up