Компонент DBTreeFilter
Домашняя страница: http://www. *****/dbt
Назначение и применение
Компонент DBTreeFilter предназначен для визуализации иерархических структур, хранящихся в реляционных источниках данных. От обычного DBTreeView компонент отличатся возможностью выбора конкретных элементов построенного дерева и получением этого набора в виде перечня отмеченных элементов. Результат можно использовать в качестве фильтра для запросов, входного параметра хранимых процедур и т. д.
Компонент разработан для языка программирования Borland Delphi версий 5, 6 и 7.
Описание
В качестве источника данных для построения дерева используется dataset (таблица, запрос, хранимая процедура). В данном случае применяется классическая для DBTreeView структура:
Код элемента | Код родителя | Наименование элемента | Признак группы |
Поле «Признак группы» является необязательным. Оно служит для ускорения построения дерева. То есть, если есть возможность указать, что у данного элемента могут быть потомки, то это лучше сделать.
Дерево можно строить в двух режимах: все сразу, до конечных уровней и постепенно, в процессе просмотра (при раскрытии ветки). Переключатель режимов - свойство BuildFullTree.
Возможено включение и отключение режима выбора конкретных элементов (свойство ChecksActive). При отключении получаем обычный компонент DBTreeView.
Поскольку компонент является наследником класса TTreeView, то полностью наследует его свойства и методы.
Кроме того, добавлены свойства:
BuildFullTree – строить или нет все дерево сразу (по умолчанию FALSE),
ChecksActive – включить/отключить режим выбора элементов (по умолчанию TRUE),
DataSet – источник данных,
FieldIdName – поле, содержащее код элемента,
FieldPrName – поле, содержащее код родителя,
FieldNmName – поле, содержащее наименование элемента,
FieldWithGroup – поле, в котором содержится признак группы (если свойство заполнено, то считается, что у данного элемента не может быть группы, если поле как текст равно '', 'FALSE' или '0'),
OutLightTree – текстовая строка, содержащая разделенные запятой коды выделенных элементов. Выбираются первые по иерархии отмеченные элементы. То есть, если у нас отмечены все элементы дерева, то это свойство будет содержать только коды элементов первого уровня.
Рассмотрим работу компонента на примере иерархического классификатора принадлежности предприятий области к отраслям народного хозяйства.
В данном случае мы видим, что строка состоит только из одного кода «168», соответствующего корневому элементу «Всего по энергосистеме»
Если мы снимем отметку, например, с элемента «V. Строительство», то получим следующий результат: корневой узел подсвечивается серым цветом (выбраны не все элементы), выходная строка состоит из семи кодов. Стоит обратить внимание, что в данном случае не выводятся коды предприятий, относящихся к лесному хозяйству, поскольку этот уровень полностью отмечен.
Если снять отметку, скажем, с Борского лесхоза, то свойство OutLightTree будет содержать уже коды отмеченных предприятий, относящихся к лесному хозяйству, поскольку сам уровень «III. Лесное хозяйство» является частично выбранным.
OutFullTree – текстовая строка, содержащая разделенные запятой коды выделенных элементов. Выбираются последние по иерархии отмеченные элементы. То есть, если у нас отмечены все элементы дерева, то это свойство будет содержать только коды элементов последних уровней. Заполнение данного свойства перед построением дерева позволяет построить дерево с сохраненными ранее отмеченными ранее элементами
Иногда возникают ситуации, когда в качестве выходной строки удобно получать коды элементов конечного уровня (например, коды видов оплат, разбитых по категориям (векселя, взаимозачеты, платежи деньгами)), поскольку это дает возможность пропустить предварительную обработку полученного набора кодов при наложении ограничения на выборку. В этом случае необходимо, чтобы дерево сразу строилось полностью (свойство BuildFullTree должно быть равно TRUE), так как иначе мы не будем иметь доступа к дочерним уровням, отмеченных групповых элементов (если только не развернем их принудительно).
Естественно, что использовать данное свойство имеет смысл только на относительно небольших структурах, когда получение «полной» выходной строки действительно себя оправдывает.
Вот как будет выглядеть это свойство в рассмотренном нами примере (в данном случае дерево сознательно построено не все, поскольку на остальных уровнях содержится достаточно много предприятий и пострадала бы наглядность):
Первый вариант: отмечены все элементы.
При этом в конечной строке отсутствует код «170» , соответствующий элементу «III. Лесное хозяйство», и код «168» (элемент «Всего по энергосистеме»), поскольку у этих элементов отмечены все потомки, коды которых и попадают в выходную строку.
Второй вариант: снята пометка с Борского лесхоза
В этом случае из выходной строки просто исключен соответствующий этому предприятию код (20273)
OutAllTree - по аналогии с OutLightTree и OutFullTree возвращает строку со списком индексов записей. Но в отличие от OutFullTree в списке присутствуют не только выделенные узлы последнего уровня, а и все промежуточные.
Для большей наглядности представляю сравнительные результаты всех трех свойств на скриншоте:

Иногда по каждой категории требуется создать список соответствий (событий). Но не всегда дерево имеет завершенный вид. Чаще всего оно достраивается в процессе работы. Так вот, например, мы имеем дерево категорий расходов и связанную таблицу расходов по каждой категории:

Спустя некоторое время организация разрослась и встал вопрос о разделении категории на конкретные транспортные средства. Но вся имеющаяся статистика не должна утратится. Более того, могут быть транспортные расходы общего назначения, которые не относятся к конкретному транспортному средству. Так вот, мы продолжаем писать общие расходы на категорию «Транспорт», а конкретные по автомобилям – в соответственные подкатегории.

В результате, когда встанет вопрос о создании запроса нам нужно будет получить идентификаторы как подкатегорий самих автомобилей так и категории «Транспорт». Это мы и получаем с поможью свойства OutAllTree.

ZeroLevParId – значение поля «Код родителя», соответствующее первому уровню иерархии (по умолчанию равно NULL)
Методы:
Build() – построение дерева.
function PathNode(Node:TTreeNode):String; возвращает путь (список всех родителей через ‘/’ + категория) для указанной ветки
function PathNodeCurrent:String; возвращает путь (список всех родителей через ‘/’ + категория) для текущей (выбранной) ветки
function PathNodeFromID(ID:integer):String; возвращает путь (список всех родителей через ‘/’ + категория) ветки, которая соответствует записи с указанным ID в DataSet

В скриншоте Вы можете увидеть результаты работы функций. Нижний СтатусБар – функция PathNodeCurrent
СтатусБар в правом окне возвращает результат функции PathNodeFromID для выбранного елемента запроса.
Особенности работы
Задания списка отмечаемых элементов перед построением дерева возможно только в свойстве OutFullTree c указанием конечных отмеченных элементов. Построение дерева на основе OutLightTree не реализовано ввиду сомнений в нужности данной операции).Соответственно для корректного отображения дерева следует выставить BuildFullTree:=True.
Построение дерева. При использовании свойства FieldWithGroup (признак группового элемента) формирование дерева идет достаточно быстро (иерархия из 6500 элементов (приведенный пример) строится 6 секунд (Pentium III 1ГГц, 256 мегабайт памяти)).
Если же данное свойство не активно, то скорость построения дерева очень сильно зависит от того, какой механизм доступа к данным используется. Если ADO, то разница настолько несущественна (на размерности в 6500 элементов – порядка 1 секунды, то есть 7 секунд на построение дерева без признака групп), что свойство FieldWithGroup можно вообще не использовать. Если же используется BDE подключение, то отключение этого свойства на больших объемах очень сильно тормозит формирование дерева. Дело в том, что в алгоритме построения для источника данных используется метод Lookup, который по разному срабатывает для ADO и BDE. Поэтому для BDE реализован несколько иной механизм, с использованием закладок, в результате чего скорость работы существенно ниже, чем при использовании ADO.
Контакты с разработчиками
- Константин Новокшанов
E-mail: *****@***ru ICQ:
- Титов Дмитрий ( координация и поддержка сайта)
E-mail: *****@***ru ICQ: 7824380
- Юрасов Вадим (идея и сборка версий)
E-mail: *****@***ru ICQ:
- Яценко Станислав
E-mail: *****@***


