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