Объект TreeView
Постановка задачи проста : надо создать структуру данных типа каталога с вложенными подкаталогами. Ну самое банальное "дерево" с бананами. А ещё лучше прикрутить к этому каталогу группу чего-либо. Ну, например, будем делать справочник зап.частей для Запорожца.
Примечание. В примере будут использоваться объекты из набора VB5 (MS Data Bound Grid Control 5.0, MS Windows Common Controls 5.0). Всё без проблем переносится на VB6 с использованием объектов OLEDB (MS DataGrid Control 6.0 (OLEDB), MS Windows Common Controls 6.0).
На начальном этапе форма будет выглядеть примерно так :

В объект ImageList1 добавим для начала две иконки, которые будут для наглядности показывать закрытую и открытую папки.
При выборе иконок лучше всего поставить в General Properties объекта ImageList1 размер 16x16. Иконки можно взять наподобие таких :
и
. Соответственно, в такой же последовательности их и добавлять в объект TreeView1. Ну это всё лирическое отступление. В процессе в форму надо будет добавить кнопки и дополнительные поля ввода.
Делаем в Access'е БД zaz.mdb и такие две таблички (tCATALOG и tSPARE) :
tCATALOG :
Field Name
|
Data Type
|
  GroupID
|
  Auto Number
|
  GroupParentKod
|
  Long Integer
|
  GroupName
|
  Text
|
|
tSPARE :
Field Name
|
Data Type
|
  SpareID
|
  Auto Number
|
  SpareGroup
|
  Long Integer
|
  SpareName
|
  Text
|
  SpareCount
|
  Single
|
  и т.д.
|
 
|
|
Для пущей верности можно указать Relationship [tCATALOG].GroupID -> [tSPARE].SpareGroup
Теперь самое главное - научить форму правильно строить "дерево" каталогов.
Module1.bas :
Option Explicit
Public gvDatabasePath As String
Public GroupBookMark() As Variant
Sub Main()
gvDatabasePath = App.Path & "\zaz.mdb"
ChDir App.Path
frmCatalog.Show
End Sub
frmCatalog.frm :
Dim i As Long
Dim NodX As Node
Private Sub Form_Load()
DataCatalog.DatabaseName = gvDatabasePath
DataSpare.DatabaseName = gvDatabasePath
DataCatalog.RecordSource = "SELECT * FROM tCATALOG WHERE GroupID>0" _
"ORDER BY GroupParentKod, GroupName"
DataCatalog.Refresh
DataSpare.RecordSource = "SELECT * FROM tSPARE"
' Можно выбрать конечно всё или добавить "WHERE SpareGroup=-1",
' чтобы ничего не попало в выборку,
' пока не будет конкретно указана нужная группа.
DataSpare.Refresh
ReadGroups
End Sub
Private Sub ReadGroups()
ReDim GroupBookMark(0)
tvCatalog.Nodes.Clear
Set NodX = tvCatalog.Nodes.Add(, , "Root", "All spares", 1, 2)
If DataCatalog.Recordset.RecordCount < 1 Then Exit Sub
With DataCatalog.Recordset
.MoveFirst
Do While .EOF = False
Select Case !GroupParentKod
Case 0
Set NodX = tvCatalog.Nodes.Add("Root", tvwChild, _
"Nodes" & !GroupID, !GroupName, 1, 2)
Case Is > 0
Set NodX = tvCatalog.Nodes.Add("Nodes" & !GroupParentKod, tvwChild, _
"Nodes" & !GroupID, !GroupName, 1, 2)
End Select
ReDim Preserve GroupBookMark(UBound(GroupBookMark) + 1)
GroupBookMark(UBound(GroupBookMark)) = .Bookmark
.MoveNext
Loop
End With
' Устанавливаем иконки для узлов (это можно сделать для того, чтобы
' явно указать, что узел содержит "группу потомков".
' Но для этого в объект ImageList1 надо добавить ещё парочку иконок
' с соответствующими изображениями)
For i = 1 To tvCatalog.Nodes.Count
If tvCatalog.Nodes.Item(i).Children > 0 Then
tvCatalog.Nodes.Item(i).Image = 3
tvCatalog.Nodes.Item(i).ExpandedImage = 4
End If
Next i
End Sub
Пояснения :
Как видно из вышеизложенного, структура таблицы tCATALOG построена по следующему принципу:
Узлы верхнего уровня имеют значение !GroupParentKod=0
Ветвь дерева, отходящая от такого узла в поле !GroupParentKod содержит значение !GroupID "родителя" и по такому же
принципу "ветвится" вглубь. При инициализации объекта DataCatalog данные сортируются как раз по полю
GroupParentKod. Таким образом обеспечивается точная последовательность создания узлов (вначале узлы верхнего уровня, затем их "чада").
При заполнении объекта tvCatalog первым делом создаётся узел "Root". Это необходимо для выбора "нулевого" уровня при создании узлов с !GroupParentKod=0. Конечно, при использовании такого механизма построения "дерева", когда нет необходимости редактировать структуру "дерева", можно не создавать "нулевой" узел, а помещать в "корень" узлы с !GroupParentKod=0:
...
Select Case !GroupParentKod
Case 0
Set NodX = tvCatalog.Nodes.Add(, , "Nodes" & !GroupID, !GroupName, 1, 2)
Case Is > 0
Set NodX = tvCatalog.Nodes.Add("Nodes" & !GroupParentKod, tvwChild, _
"Nodes" & !GroupID, !GroupName, 1, 2)
End Select
...
uncle-b@cybergal.com (Борис
Феофанов)
Klaipeda, Lithuania