Дерево значений является одним из популярных типов данных, часто встречающихся на формах и конфигурации. Важным его преимуществом является заложенная платформой иерархичность, которой удобно воспользоваться в некоторых ситуациях, например, осуществить поиск по определенной группе элементов или получить отдельные итоговые суммы в различных категориях. Дерево значений в 1С – достаточно эффективный инструмент, достойный, чтобы разработчики тратили на его изучение свое время.
- Размещение на форме и заполнение дерева значений
- Работа с заполненным деревом значений
- Управляемые формы
- Обычные формы
- Дерево значений
- Дерево значений на форме
- Заполнение дерева значений
- Обход дерева значений
- Как свернуть и развернуть дерево значений
- Как удалить строку и очистить дерево значений
- Запрос и дерево значений
- Дерево значений в таблицу значений и обратно
- Отбор в дереве значений
Размещение на форме и заполнение дерева значений
Чтобы на управляемой форме вывести дерево значений, необходимо добавить новый реквизит, выбрать нужный тип, добавить колонки и перетащить влево. На вопрос о добавлении колонок ответьте утвердительно, и перед вами предстанет общий вид дерева значений. Чтобы увидеть какие-либо записи, необходимо добавить строки дерева значений 1С с нужными данными.
Существует несколько способов заполнения дерева значений нужными нам свойствами с определенной иерархией. Самый простой вариант – заполнить вручную, последовательно добавляя элементы и внимательно самостоятельно соблюдая иерархию. Естественно, при большом количестве элементов данный вариант не должен рассматриваться разработчиками 1С. Данный способ вывода информации состоит из следующих операторов:
На стороне сервера:
- Получение значения реквизита;
- Добавление элементов с учетом иерархии;
- Возврат значения в элемент формы на клиенте для вывода пользователю.
На стороне клиента:
- Получение элементов дерева;
- Добавление новых.
Таким способом можно оформить на управляемой форме 1С небольшое дерево значений или простую иерархию, используя цикл. Однако часто возникает задача представить на форме сложный иерархический справочник из базы данных. И здесь на помощь придет помещение результата запроса в дерево на форме. Алгоритм достаточно прост и логичен:
- Создаем запрос и указываем нужные нам условия. Важно, чтобы псевдонимы совпадали с наименованием колонок дерева значений на форме;
- Получаем данные с нужным видом обхода. Если не указывать, то получится не иерархическая таблица значений.
При многократном использовании управляемой формы приходится очищать реквизиты. Не является исключением и дерево значений, если нам нужно получать актуальную информацию. Полностью очистить наш реквизит можно различными способами без особых усилий программиста:
Вышеперечисленные действия достаточно просты и не требуют усилий. Намного сложнее действия с конкретными строками, которые тоже необходимо использовать в работе. Ведь зачастую мы не будем иметь ни малейшего понятия о количестве строк в дереве, его иерархии, ее глубине и пр. Именно корректная работа с данными произвольной структуры требуется от качественно разработанной функциональности решения для анализа и обработки информации дерева значений.
Работа с заполненным деревом значений
В первую очередь, нужно научиться работать с данными, получая их из дерева. Для этого придется написать процедуру обхода строк дерева значений. Данные можно получить на сервере или клиенте, причем разница в алгоритмах будет небольшая. Ниже представлен алгоритм обхода дерева с краткими пояснениями операторов:
На клиентской стороне:
- Вызываем процедуру, используя в качестве параметров строки дерева;
- Внутри процедуры в цикле перебираем строки и проверяем наличие вложенных строк внутри каждой из них. Если таковые обнаружились, то снова вызываем эту же процедуру. Таким способом мы последовательно обойдем все строки, какой бы вложенностью не обладало наше дерево значений.
На серверной стороне:
- Получаем объект с формы;
- Вызываем процедуру с объектом в качестве параметра;
- В цикле по каждой строке дерева проверяем количество вложенных элементов и при их наличии снова вызываем процедуру.
Иногда в процессе обхода строк нам может потребоваться удалить что-либо. Для этого используется метод «Удалить(_параметр_)», для которого в качестве параметра может использоваться индекс или непосредственно строка. Так как в процессе обхода вы рассматриваете все строки по отдельности, не составит труда удалить некоторые из них. Будьте внимательны, так как при удалении строки удаляются все вложенные элементы.
Также достаточно распространенной задачей является преобразование дерева значений в таблицу значений. Так как нам нельзя терять иерархию, в таблице будет на 2 поля больше, чем в дереве – добавятся идентификатор и родитель. Заполнить таблицу с сохранением структуры мы сможем с помощью рекурсивной процедуры.
Целиком алгоритм состоит из:
- Вызов процедуры с указанием начального идентификатора;
- Цикл с добавлением данных в таблицу значений и проверкой на наличие вложенных элементов в дереве в каждой итерации. При их наличии снова начинается вызов рекурсивной процедуры.
Зачастую пользователям бывает мало просто добавить дерево значений в 1С на управляемую форму. Постоянно поступают запросы, чтобы была возможность посмотреть всю структуру. Для этого придется развернуть дерево значений прямо на глазах у пользователя. В 1С это можно сделать, обойдя в цикле все строки и воспользовавшись одним из их методов:
Также могут случаться ситуации, когда нужно свернуть имеющееся дерево. Для сворачивания конкретной строки можно воспользоваться методом «Свернуть(_Строка_)», аналогичным по синтаксису вышеописанному «Развернуть()». Чтобы полностью свернуть все дерево, придется воспользоваться рекурсивной функцией. Ее код достаточно прост и поддерживает общую методологию работы с деревом значений:
Одним из сложных нюансов, связанных с деревом значений, является отсутствие возможности отбора, когда родитель не удовлетворяет условию, а подчиненный элемент удовлетворяет. Нет однозначного ответа, что делать в подобных ситуациях, поэтому разработчики 1С решили не добавлять стандартную возможность фильтрации для дерева значений. Однако с этим можно справиться, разработав свою методику, например, скопировать дерево, удалить неподходящие значения и изменить иерархию.
Созданный в платформе 1С тип «Дерево значений» отлично подходит для задач отображения иерархических списков и не только. Пользуясь им грамотно, можно существенно сэкономить время и удовлетворить требования пользователей по визуализации необходимых им данных, легко загрузив данные в дерево, обойти их и отразить развернутый список на управляемой форме.
рубрики: Работа с формами | Дата: 12 Ноябрь, 2016
Скачать обработку с примерами из статьи: professia1c_TreeValue.epf
Платформа: 8.3; Тип формы: управляемая.
В этой статье рассмотрим как можно выгружать результат запроса в
дерево значений на форме. Разберем этот вопрос как для обычных,
так и для управляемых форм.
В некоторм роде эта статья пересекается со статьей про
иерархический обход результата запроса
Поэтому и пример возьмем такой же. То есть когда нам надо сделать запрос к таблице:
Период | Склад | Товар | Цена |
---|---|---|---|
01.01.2016 | Центральный | Ручка | 30 |
01.01.2016 | Офис | Карандаш | 15 |
05.01.2016 | Центральный | Ручка | 45 |
10.01.2016 | Офис | Карандаш | 25 |
15.01.2016 | Центральный | Степлер | 150 |
17.01.2016 | Офис | Дырокол | 200 |
и разместить результат на форме в виде дерева значений вот в таком виде:
Центральный | |||
---|---|---|---|
Ручка | |||
01.01.2016 | 30 | ||
05.01.2016 | 45 | ||
Степлер | |||
15.01.2016 | 150 | ||
Офис | |||
Карандаш | |||
01.01.2016 | 15 | ||
10.01.2016 | 25 | ||
Дырокол | |||
17.01.2016 | 200 |
А теперь рассмотрим как это можно сделать на управляемых и на обычных формах.
Управляемые формы
Для демонстрации создадим внешнюю обработку. Добавим форму. В реквизитах формы
создаем реквизит с типом ДеревоЗначений. Уже в этот реквизит добавляем
колонки реквизита (имена должны совпадать с именами полей в запросе).
Перетаскиваем наше дерево значений на форму. Ну и конечно добавим команду, которая
будет запускать заполнение дерева.
В модуле формы пишем вот такой код (текст запроса по формированию временной таблицы
с исходными данными полностью приводить не буду. Его можно взять в вышеуказанной статье):
Здесь стоит обратить внимание на два момента. Первое — это то, что имена полей
запроса и полей дерева значений должны совпадать.
И второе — это метод
ЗначениеВРеквизитФормы(), который помещает сформированное дерево
значений в реквизит формы.
После выполнения кода в форме получаем вот такое дерево значений:
Обычные формы
Создадим тестовую обработку и добавим реквизит с типом ДеревоЗначений.
Создадим обычную форму, добавим на нее табличное поле и в свойствах в качестве
источника данных укажем ранее добавленный реквизит
Как видим в отиличие от управляемых в обычных формах нет необходимости заранее
создавать колонки для дерева значений.
Переходим в модуль формы. Текст запроса опустим, т.к. он будет точно такой же
как и для управляемой формы. Немного различаться будет обработка результата
запроса.
Для тех кто первый раз сталкивается с такой задачей основная трудность — это
догадаться о необходимости применения метода СоздатьКолонки()
к табличному полю формы, т.к. без него поле остается пустым.
Запускаем выполнение обработки и получаем следующую картину
В последнее время аномально часто мне в работе попадалось дерево значений, поэтому решил написать на эту тему статью.
Попробую рассмотреть способы решения основных задач связанных с деревом значений, при этом постараюсь писать «без воды».
Дерево значений
Из названия объекта понятно, что дерево значений служит для хранения/отображения какой-либо иерархической информации. Каждая строка дерева значений может иметь какое-то количество подчиненных строк, при этом такие операции как поиск, сортировка, подсчет итогов можно проводит с учетом уровня иерархии и подчиненных строк.
Кроме этого, каждая строка дерева значений имеет свойства «Родитель» и «Строки».
Дерево значений на форме
Визуальное представление дерева значений обеспечивает элемент «Табличное поле».
Дерево значений на обычной форме
Дерево значений на управляемой форме
Заполнение дерева значений
При заполнении дерева значений нужно помнить, что сам объект «ДеревоЗначений» и все его строки имеют свойство «Строки»и добавление новых строк на любом уровне дерева осуществляется через это свойство.
Сам же объект «ДеревоЗначений» имеет еще и свойство «Колонки», которое ничем не отличается от аналогичного свойства у таблицы значений.
Небольшой пример программного заполнения таблицы значений для управляемых форм:
Обход дерева значений
Обход всех строк дерева значений делается при помощи рекурсии, вот так будет выглядеть код для обхода дерева созданного в примере выше:
Как свернуть и развернуть дерево значений
Сворачивается и разворачивается дерево значений очень просто.
Привел три примера: для сворачивания текущей строки, для сворачивания строк верхнего уровня, для сворачивания вообще всех строк (рекурсия).
Два примера: для разворачивания текущей строки и для разворачивания всех строк. У метода «Развернуть» есть дополнительный параметр, который позволяет указать нужно ли разворачивать подчиненные строки.
Как удалить строку и очистить дерево значений
Тут опять же все просто, нужно помнить, что при удалении/очистке строки, все подчиненные строки удаляются.
Очистить дерево значений:
Точно также можно очистить от подчиненных элементов другую другую строку.
Удалить строку дерева значений не сложнее — нужно только знать ее индекс:
Запрос и дерево значений
Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом «Выгрузить» и указать параметр «ТипОбхода» отличным от того, что стоит по умолчанию, т.е. «ПоГруппировкам» или «ПоГруппировкамСИерархией».
Если на форме имеется реквизит «ДеревоЗначений» и связанный с ним визуальный элемент, то можно сделать примерно так:
Причем полного совпадения колонок и типов не требуется — лишние колонки будут просто отброшены, а колонки с различными типами будут заполнены пустыми значениями.
Дерево значений в таблицу значений и обратно
Преобразовать дерево значений в таблицу значений и наоборот достаточно просто, ведь дерево значений это та же таблица значений, но с дополнительной колонкой — «Родитель». У меня есть отдельная статья о том как преобразовать дерево значений в таблицу значений и обратно.
Отбор в дереве значений
Стандартного отбора в дереве значений не предусмотрено. Так получилось потому, что непонятно как разрешать ситуацию, когда родительский элемент не удовлетворяет условию отбора, а подчиненные ему элементы удовлетворяют.
Таким образом, если Вам нужно реализовать отбор в дереве значений, то начать нужно с решения именно этой проблемы. А уже после этого можно придумать несколько способов реализовать задуманное.
Первый способ — накладывать отбор до вывода дерева значений (в запросе например). Это не классический отбор, но в тех случаях когда этот способ применим, то следует применять именно его, так как это почти всегда быстрее и правильнее чем что-либо другое.
Второй способ — перебор всех строк дерева значений. Описывать здесь особенно нечего, нужно просто взять обход дерева значений, проверять каждую строку на соответствие условию отбора и удалять лишние строки.
Еще один способ заключается в том, чтобы преобразовать дерево значений в таблицу значений, сделать отбор в таблице значений, проконтролировать результат (почистить «хвосты» — строки, родитель которых не удовлетворил условию отбора) и выполнить обратное преобразование в дерево значений.
На этом все, рассказал все, что знал, надеюсь мне удалось сэкономить Вам немного времени.
Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.