Morjes, eli olen tässä jonkin aikaa tuota vb.netiä koittanut harjoitella.
Ohjelmana käytän Visual Studio 2005.
Form, jossa TreeView (Treeview1) ja Painike (Button1), nappulaa painamalla treeview:n täyttyy.
Access -kanta (Database1), jossa table1, jossa kentät ID, Henkilö, Esine.
Eli tarkoitus on, että puunäkymä olisi seuraava:
Henkilö A
-------EsineA
-------EsineB
Henkilö B
-------EsineC
Mutta ongelmaksi muodostuu, että kyseisessä tilanteessa formille ilmestyy henkilö A 2 kertaa, eli:
Henkilö A
-------EsineA
-------EsineB
Henkilö A
-------EsineA
-------EsineB
Henkilö B
-------EsineC
Eli olisiko mahdollista estää nuo tuplaantuneet nodet?
Alla formin koodi
Imports System.Data.OleDb
Public Class Form9
Inherits System.Windows.Forms.Form
Dim olecon As OleDb.OleDbConnection
Dim daHenkilö As OleDb.OleDbDataAdapter
Dim daEsine As OleDb.OleDbDataAdapter
Dim dsgeneral As DataSet
Private Sub Form9_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim Kanta As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Temp\Database1.mdb;User ID=Admin;Password="
olecon = New OleDb.OleDbConnection(Kanta)
Catch
MsgBox(Err.Description)
Exit Sub
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TreeView1.Nodes.Clear()
olecon.Open()
daHenkilö = New OleDb.OleDbDataAdapter("select Henkilö from Table1", olecon)
dsgeneral = New DataSet()
daHenkilö.Fill(dsgeneral, "Henkilö")
Dim I%, j%, Henkilö$, Esine$
For I = 0 To dsgeneral.Tables("Henkilö").Rows.Count - 1
Henkilö = dsgeneral.Tables("Henkilö").Rows(I).Item("Henkilö").ToString
TreeView1.Nodes.Add(Henkilö)
TreeView1.Nodes(I).ImageIndex = 0
daEsine = New OleDb.OleDbDataAdapter("select * from Table1 where Henkilö='" & Henkilö & "'", olecon)
daEsine.Fill(dsgeneral, "Esine")
dsgeneral.Tables("Esine").Clear()
daEsine.Fill(dsgeneral, "Esine")
For j = 0 To dsgeneral.Tables("Esine").Rows.Count - 1
Esine = dsgeneral.Tables("Esine").Rows(j).Item("Esine").ToString
Dim EsineNode As TreeNode
EsineNode = TreeView1.Nodes(I)
EsineNode.Nodes.Add(Esine)
EsineNode.Expand()
Next
Next
End Sub
Private Sub TreeView1_AfterCollapse(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterCollapse
End Sub
Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
End Sub
End ClassKokeile korvata "select Henkilö from Table1" tällä "select distinct Henkilö from Table1"
Vaikka tuota koodia ja toimintalogiikkaa voisi siistiä paljonkin, niin en todellakaan jaksa hirveästi paneutua kun taulujen nimet on tyyliin "Table1", tietorakennetta ei ole kerrottu, jne.
Yleisesti ottaen sanoisin, että koko tietomassan voisit hakea yhdellä kyselyllä nykyisen n+1 kyselyn asemesta, missä n on kannassa oleva henkilöiden määrä.
Moikka kSiit!
sinuna vääntelisin jutskan näin...
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
Inherits System.Windows.Forms.Form
Dim olecon As OleDbConnection = Nothing
Dim da As OleDbDataAdapter = Nothing
Dim ds As DataSet = Nothing
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim Kanta As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
+ "C:\Temp\Database1.mdb;User ID=Admin;Password="
olecon = New OleDbConnection(Kanta)
Catch
MsgBox(Err.Description)
Exit Sub
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Try
olecon.Open
Catch
MsgBox(Err.Description)
Exit Sub
End Try
treeView1.Nodes.Clear
da = New OleDbDataAdapter( _
"SELECT Henkilö, Esine FROM Table1", olecon)
ds = New DataSet()
da.Fill(ds, "Table1")
da = Nothing
Dim i As Integer
For i = 0 To ds.Tables("Table1").Rows.Count - 1
Dim dRow As DataRow = ds.Tables("Table1").Rows(i)
TreeView1.Nodes.Add(dRow("Henkilö").ToString)
TreeView1.Nodes(i).ImageIndex = 0
Dim EsineNode As TreeNode = TreeView1.Nodes(i)
'jos 'Esine' kenttä sisältää pilkulla (,)
'erotettuja arvoja esim. (EsineA,EsineB,jne.) niin...
If dRow("Esine").ToString.Contains(",") Then
Dim strArray() As String = _
dRow("Esine").ToString.Split(",".ToCharArray)
For j As Integer = 0 To strArray.Length - 1
EsineNode.Nodes.Add(strArray(j))
Next j
strArray = Nothing
Else 'muutoin...
EsineNode.Nodes.Add(dRow("Esine").ToString)
End If
EsineNode = Nothing
dRow = Nothing
Next i
treeView1.ExpandAll
olecon.Close
ds = Nothing
End Sub
Private Sub Form1_FormClosing(ByVal sender As System.Object, _
ByVal e As System.FormClosingEventArgs) Handles MyBase.FormClosing
olecon = Nothing
End Sub
End ClassNean ajatus laittaa saman henkilöön esineet yhdelle riville pilkulla eroteltuna on kylläkin huonoa tietokantasuunnittelua eikä millään tavalla tarpeellinen edes usean kyselyn tekemisen välttämiseen.
Eli suosittelen olemaan menemättä huonompaan suuntaan tuossa asiassa.
Moikka taas!
Grez: tietokannoissa on itsessään erinäistäkin erotinmerkeillä erotettua dataa vaikkei ehkä käyttäjälle näkyisikään. Huonoa suunnitteluako?
mutta väännellään nyt sitten näin...
Imports System.Data
Imports System.Data.OleDb
Public Class Form1
Inherits System.Windows.Forms.Form
Private olecon As OleDbConnection = Nothing
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim Kanta As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
+ "C:\Temp\Database1.mdb;User ID=Admin;Password="
olecon = New OleDbConnection(Kanta)
Catch
MsgBox(Err.Description)
Exit Sub
End Try
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Try
olecon.Open
Catch
MsgBox(Err.Description)
Exit Sub
End Try
treeView1.Nodes.Clear
Dim da As OleDbDataAdapter = New OleDbDataAdapter( _
"SELECT Henkilö, Esine FROM Table1", olecon)
Dim ds As New DataSet
da.Fill(ds, "Table1")
da = Nothing
olecon.Close
For i As Integer = 0 To ds.Tables("Table1").Rows.Count - 1
Dim dRow As DataRow = ds.Tables("Table1").Rows(i)
Dim IsExisting As Boolean = False
For j As Integer = 0 To TreeView1.Nodes.Count -1
If TreeView1.Nodes(j).Text = dRow("Henkilö").ToString Then
IsExisting = True: Exit For
End If
Next j
If Not IsExisting Then
TreeView1.Nodes.Add(dRow("Henkilö").ToString)
TreeView1.Nodes(TreeView1.Nodes.Count - 1).ImageIndex = 0
For j As Integer = 0 To ds.Tables("Table1").Rows.Count - 1
If ds.Tables("Table1").Rows(j)("Henkilö") _
.ToString = dRow("Henkilö").ToString Then
dRow = ds.Tables("Table1").Rows(j)
Dim EsineNode As TreeNode = _
TreeView1.Nodes(TreeView1.Nodes.Count - 1)
EsineNode.Nodes.Add(dRow("Esine").ToString)
EsineNode = Nothing
End If
Next j
End If
dRow = Nothing
Next i
treeView1.ExpandAll
ds = Nothing
End Sub
Private Sub Form1_FormClosing(ByVal sender As System.Object, _
ByVal e As System.FormClosingEventArgs) Handles MyBase.FormClosing
olecon = Nothing
End Sub
End ClassKiitoksia vastauksista, lähti kyllä tuolla "select distinct":lläkin toimimaan.
Mutta pitää katsoa tuo neau33:n vaihtoehto läpi, joka on varmasti parempi kuin tuo minun.
Aihe on jo aika vanha, joten et voi enää vastata siihen.