1с управляемые формы дерево значений примеры

Работа с деревом значений в 1С

В последнее время аномально часто мне в работе попадалось дерево значений, поэтому решил написать на эту тему статью.

Попробую рассмотреть способы решения основных задач связанных с деревом значений, при этом постараюсь писать «без воды».

Дерево значений

Из названия объекта понятно, что дерево значений служит для хранения/отображения какой-либо иерархической информации. Каждая строка дерева значений может иметь какое-то количество подчиненных строк, при этом такие операции как поиск, сортировка, подсчет итогов можно проводит с учетом уровня иерархии и подчиненных строк.

Кроме этого, каждая строка дерева значений имеет свойства «Родитель» и «Строки».

Дерево значений на форме

Визуальное представление дерева значений обеспечивает элемент «Табличное поле».

Заполнение дерева значений

При заполнении дерева значений нужно помнить, что сам объект «ДеревоЗначений» и все его строки имеют свойство «Строки»и добавление новых строк на любом уровне дерева осуществляется через это свойство.

Сам же объект «ДеревоЗначений» имеет еще и свойство «Колонки», которое ничем не отличается от аналогичного свойства у таблицы значений.

Небольшой пример программного заполнения таблицы значений для управляемых форм:

Обход дерева значений

Обход всех строк дерева значений делается при помощи рекурсии, вот так будет выглядеть код для обхода дерева созданного в примере выше:

Как свернуть и развернуть дерево значений

Сворачивается и разворачивается дерево значений очень просто.

Привел три примера: для сворачивания текущей строки, для сворачивания строк верхнего уровня, для сворачивания вообще всех строк (рекурсия).

Два примера: для разворачивания текущей строки и для разворачивания всех строк. У метода «Развернуть» есть дополнительный параметр, который позволяет указать нужно ли разворачивать подчиненные строки.

Как удалить строку и очистить дерево значений

Тут опять же все просто, нужно помнить, что при удалении/очистке строки, все подчиненные строки удаляются.

Точно также можно очистить от подчиненных элементов другую другую строку.

Удалить строку дерева значений не сложнее — нужно только знать ее индекс:

Запрос и дерево значений

Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом «Выгрузить» и указать параметр «ТипОбхода» отличным от того, что стоит по умолчанию, т.е. «ПоГруппировкам» или «ПоГруппировкамСИерархией».

Читайте также:  Черноплодка дерево как выглядит

Если на форме имеется реквизит «ДеревоЗначений» и связанный с ним визуальный элемент, то можно сделать примерно так:

Причем полного совпадения колонок и типов не требуется — лишние колонки будут просто отброшены, а колонки с различными типами будут заполнены пустыми значениями.

Дерево значений в таблицу значений и обратно

Преобразовать дерево значений в таблицу значений и наоборот достаточно просто, ведь дерево значений это та же таблица значений, но с дополнительной колонкой — «Родитель». У меня есть отдельная статья о том как преобразовать дерево значений в таблицу значений и обратно.

Отбор в дереве значений

Стандартного отбора в дереве значений не предусмотрено. Так получилось потому, что непонятно как разрешать ситуацию, когда родительский элемент не удовлетворяет условию отбора, а подчиненные ему элементы удовлетворяют.

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

Первый способ — накладывать отбор до вывода дерева значений (в запросе например). Это не классический отбор, но в тех случаях когда этот способ применим, то следует применять именно его, так как это почти всегда быстрее и правильнее чем что-либо другое.

Второй способ — перебор всех строк дерева значений. Описывать здесь особенно нечего, нужно просто взять обход дерева значений, проверять каждую строку на соответствие условию отбора и удалять лишние строки.

Еще один способ заключается в том, чтобы преобразовать дерево значений в таблицу значений, сделать отбор в таблице значений, проконтролировать результат (почистить «хвосты» — строки, родитель которых не удовлетворил условию отбора) и выполнить обратное преобразование в дерево значений.

На этом все, рассказал все, что знал, надеюсь мне удалось сэкономить Вам немного времени.

Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

(оценок: 36, средняя оценка: 4,64 из 5)

Источник

Дерево значений в 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 Тогда ПреобразоватьВ_ТЗ(Строка, ТаблицаЗначений, НовСтрока.ГУИД); КонецЕсли; КонецЦикла; КонецПроцедуры 

Используя данный способ можно легко преобразовать таблицу значений обратно в дерево значений. Из примера «ГУИД» это уникальный идентификатор строки, а «Родитель» уникальный идентификатор родителя. Если обратного преобразования не требуется можно исключить использование колонок «Родитель» и «ГУИД».

Источник

Оцените статью