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 Class
Kokeile 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 Class
Nean 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 Class
Kiitoksia 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.