Помогите правильно заполнить TreeView данными из базы данных

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Помогите правильно заполнить TreeView данными из базы данных

Сообщение sergey-911 » 22.07.2008 (Вт) 10:05

Доброго времени суток уважаемые.
Проблема заполнить TreeView данными из базы данных.
Для примера возьмем Access.
Имя файла – “RECURSIVE.mdb”, Название таблицы – “tblKOI”, структура таблицы:

ID - Счетчик
ParentID - Числовой
KOI - Текстовый

Таблица заполнена данными:
__________________________________________
ID | ParentID | KOI
---------------------------------------------------------------
1 | NULL | Сборка1
2 | 1 | КОИ1
3 | 1 | КОИ2
4 | 2 | КОИ1_КОИ3
__________________________________________

Должно получиться дерево:

+ Сборка1
|-- КОИ1
| |-- КОИ1_КОИ3
|
|-- КОИ2

Ничего, кроме:

+ Сборка1
|-- КОИ1
|-- КОИ2
|-- КОИ1_КОИ3

у меня не получается…
Помогите пожалуйста, проект горит, все сроки вышли.
Буду рад любой информации!!!
С уважением, Сергей.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 22.07.2008 (Вт) 10:17

Пытаюсь заполнить TreeView следующим образом:
Код: Выделить всё

        'Создание объекта Connection
        Dim cn As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection
        'Поиск файла "Biblio.mdb" в текущей директории
        Dim s As String
        s = CurDir()
        If Microsoft.VisualBasic.Right(s, 1) _
         <> "\" Then s = s & "\"
        s = s & "RECURSIVE.mdb"
        'Строка подключения
        cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & s
        'Открытие соединения
        cn.Open()
        'Создание объекта Command
        Dim cmd As System.Data.OleDb.OleDbCommand = cn.CreateCommand()
        cmd.CommandText = "SELECT ID, ParentID, KOI FROM tblKOI"
        'Создание объекта DataReader
        Dim rdr As System.Data.OleDb.OleDbDataReader = cmd.ExecuteReader()

        'Вывод результатов в TreeView
        TreeView1.Nodes.Clear()
        Dim pNode As TreeNode ' parent
        Dim cNode As TreeNode ' child
        Do
            While rdr.Read()
                If rdr.Item(1).ToString = Nothing Then
                    pNode = TreeView1.Nodes.Add(rdr.Item(2).ToString) ' add parent
                    pNode.Tag = rdr.Item(0).ToString
                Else
                    cNode = New TreeNode
                    cNode.Text = rdr.Item(2).ToString
                    cNode.Tag = rdr.Item(0).ToString
                    pNode.Nodes.Add(cNode)
                End If
            End While
        Loop While rdr.NextResult()
        TreeView1.EndUpdate()
    End Sub

Для удобства, в архиве прикреплен вышеуказанный проект, на VB.2008, с файлом Access
Вложения
TreeView_Access.rar
вышеуказанный проект, на VB.2008, с файлом БД
(68.35 Кб) Скачиваний: 287
С уважением, Сергей.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 22.07.2008 (Вт) 11:07

Код: Выделить всё

'***************************************
'Заполнение дерева рекурсивным обходом узлов, начиная с узла iPar
'***************************************
Public Sub FillTreeRecurs(iPar As Long, ByRef oTree As TreeView)
Dim oN1 As Node, s As String, tl As Long
    tl = GTC
    Dim rCh As Recordset
    If iPar = 0 Then oTree.Nodes.Clear
    Set rCh = GetChild(iPar)
    If rCh.RecordCount < 1 Then Exit Sub
    Do While Not rCh.EOF
        s = Trim(Str(rCh.Fields("ID").Value))
            If iPar > 0 Then
                Set oN1 = oTree.Nodes.Add("c" & Trim(Str(iPar)), tvwChild, "c" & _
                        s, rCh.Fields("Group_Name"))
            Else
                Set oN1 = oTree.Nodes.Add(, , "c" & s, _
                        rCh.Fields("Group_Name"))
            End If
            FillTreeRecurs rCh.Fields("ID"), oTree

        rCh.MoveNext
    Loop
End Sub

'Возвращает набор записей с прямыми потомками
Public Function GetChild(iID As Long) As Recordset
    Set GetChild = recGr.Clone
    GetChild.Filter = "Parent_ID=" & iID
End Function

Взято из проекта.
В recGr - все записи таблицы.
label:
cli
jmp label

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 22.07.2008 (Вт) 14:36

Спасибо iGrok.
Это не совсем то. Твой проект, по-видимому был написан на VB.6. Переделать под VB.Net не получается...
Код: Выделить всё

Public Class Form1
    Dim recGr As System.Data.OleDb.OleDbDataReader

    Private Sub btnTreeView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTreeView.Click
        'Создание объекта Connection
        Dim cn As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection
        'Поиск файла "Biblio.mdb" в текущей директории
        Dim s As String
        s = CurDir()
        If Microsoft.VisualBasic.Right(s, 1) _
         <> "\" Then s = s & "\"
        s = s & "RECURSIVE.mdb"
        'Строка подключения
        cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & s
        'Открытие соединения
        cn.Open()
        'Создание объекта Command
        Dim cmd As System.Data.OleDb.OleDbCommand = cn.CreateCommand()
        cmd.CommandText = "SELECT ID, ParentID, KOI FROM tblKOI"
        'Создание объекта DataReader
        Dim rdr As System.Data.OleDb.OleDbDataReader = cmd.ExecuteReader()

        'Вывод результатов
        recGr = rdr
        Call FillTreeRecurs(1, TreeView1)
    End Sub

    '***************************************
    'Заполнение дерева рекурсивным обходом узлов, начиная с узла iPar
    '***************************************
    Public Sub FillTreeRecurs(ByVal iPar As Long, ByRef oTree As TreeView)
        Dim oN1 As TreeNode, s As String
        Dim rCh As System.Data.OleDb.OleDbDataReader
        If iPar = 0 Then oTree.Nodes.Clear()
        rCh = GetChild(iPar)
        If rCh.FieldCount < 1 Then Exit Sub
        Do
            While rCh.Read()
                s = Trim(Str(rCh.Item("ID").Value))
                If iPar > 0 Then
                    oN1 = oTree.Nodes.Add("c" & iPar.ToString, TreeView1, "c" & s, rCh.Item("KOI"))
                Else
                    oN1 = oTree.Nodes.Add(, , "c" & s, rCh.Item("KOI"))
                End If
                FillTreeRecurs(rCh.Item("ID"), oTree)
            End While
        Loop While rCh.NextResult()
    End Sub

    'Возвращает набор записей с прямыми потомками
    Public Function GetChild(ByVal iID As Long) As System.Data.OleDb.OleDbDataReader
        GetChild = recGr
        GetChild.Filter = "ParentID=" & iID
        Return GetChild
    End Function
End Class


Вывыливаются ошибки в строках:
Код: Выделить всё

oN1 = oTree.Nodes.Add("c" & iPar.ToString, TreeView1, "c" & s, rCh.Item("KOI"))
oN1 = oTree.Nodes.Add(, , "c" & s, rCh.Item("KOI"))
GetChild.Filter = "ParentID=" & iID

К тому же мне нужно заполнить TreeView всеми данными из таблицы, а не только указанную ветку.
Может, я чего не понял, но все равно спасибо!
Тема открыта, жду Вашу помощь.
С уважением, Сергей.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Сообщение iGrok » 22.07.2008 (Вт) 16:41

Ну.. Указываешь 0 в номере ветки - вот тебе и все данные.
Ну только ParentID вместо NULL надо поставить 0 для "корня дерева".
Ну так это простым запросом..

Да, на Vb6.
VB.NET'овский TreeView не юзал - так что на что именно ругается не скажу. Опять же, попробуй не OleDbDataReader, а ADODB.Recordset..

Если не поможет - сорри. )
label:
cli
jmp label

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 22.07.2008 (Вт) 18:00

Код: Выделить всё
    Private Sub btnTreeView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTreeView.Click
        'Создание объекта Connection
        Dim cn As System.Data.OleDb.OleDbConnection = New System.Data.OleDb.OleDbConnection
        'Поиск файла "Biblio.mdb" в текущей директории
        Dim s As String
        s = CurDir()
        If Microsoft.VisualBasic.Right(s, 1) _
         <> "\" Then s = s & "\"
        s = s & "RECURSIVE.mdb"
        'Строка подключения
        cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & s
        'Открытие соединения
        cn.Open()
        'Создание объекта Command
        Dim cmd As System.Data.OleDb.OleDbCommand = cn.CreateCommand()
        cmd.CommandText = "SELECT ID, ParentID, KOI FROM tblKOI"
        'Создание объекта DataReader
        Dim rdr As System.Data.OleDb.OleDbDataReader = cmd.ExecuteReader()

        'Вывод результатов
        TreeView1.Nodes.Clear()
        Dim FindedNodes(0) As TreeNode
        Dim ID As String = ""
        Dim ParentID As String = ""
        Dim KOI As String = ""

        Do
            While rdr.Read()
                ID = rdr.Item(0).ToString
                ParentID = rdr.Item(1).ToString
                KOI = rdr.Item(2).ToString

                If ParentID Is String.Empty Then
                    TreeView1.Nodes.Add(ID, KOI) ' add parent
                Else
                    FindedNodes = TreeView1.Nodes.Find(ParentID, True)
                    FindedNodes(0).Nodes.Add(ID, KOI)
                End If

            End While
        Loop While rdr.NextResult()

        TreeView1.EndUpdate()
        TreeView1.ExpandAll()

        cn.Close()
    End Sub


ADD:
вместо этого
Код: Выделить всё
        If Microsoft.VisualBasic.Right(s, 1) <> "\" Then s = s & "\"
        s = s & "RECURSIVE.mdb"
используй
Код: Выделить всё
s = IO.Path.Combine(Application.StartupPath, "RECURSIVE.mdb")
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 22.07.2008 (Вт) 22:48

iGrok писал(а):Ну.. Указываешь 0 в номере ветки - вот тебе и все данные.
Ну только ParentID вместо NULL надо поставить 0 для "корня дерева".
Ну так это простым запросом..

Да, на Vb6.
VB.NET'овский TreeView не юзал - так что на что именно ругается не скажу. Опять же, попробуй не OleDbDataReader, а ADODB.Recordset..

Если не поможет - сорри. )


iGrok, спасибо за помощь и отзывчивость.
NULL, в данной ситуации, тоже самое, что и 0. Просто в разных учебниках пишут по разному.
Впрочем, без разницы, испольэовать OleDbDataReader или ADODB.Recordset. Подключение к БД Access я взял для примера. Естественно, реальная БД будет на MS SQL 2005. Подключение будет через SqlClient, а следовательно набор данных в DataSet. Роли не играет.
Но все-равно, большое человеческое спасибо! :D
С уважением, Сергей.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 22.07.2008 (Вт) 22:54

Спасибо Nord777 ОГРОМНОЕ! Все отлично работает!
Готовый пример в архиве, вдруг кому пригодится! :D
Вложения
TreeView_Access.rar
Готовый пример заполнения TreeView
(69.29 Кб) Скачиваний: 629
С уважением, Сергей.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 55

    TopList