Sortieren mehrerer Felder in einer Datatable (typisiertes Dataset)

  • VB.NET
  • .NET (FX) 4.0

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Sortieren mehrerer Felder in einer Datatable (typisiertes Dataset)

    Ich habe ein typisertes Dataset und wollte eine Tabelle nach 2 Spalten sortieren.
    Die Tabelle muß sequenziell gelesen werden um ein Treeview aufzubauen.Die erste Sortierspalte enthält dazu die Verzeichnistiefe und die 2. eine Sortierung innnerhalb der gleichen Ebene.
    Wie bewerkstellige ich das am effektivsten ?
    Tabelle.defaultviewsort srrgt zwar dafür das die Zeilen in einem Steuerelement richtig sortiert angezeigt werden, aber beim Durchlaufen der Zeilen hat es keinen Einfluß.
    Bei Tabelle.select habe ich bisher nur die Möglichkeit gefunden nach einer Spalte zu sortieren.

    VB.NET-Quellcode

    1. Private _dtOE As dsMA_Rechner.tbl_OrgstrukturDataTable
    2. Public Property dtOE As dsMA_Rechner.tbl_OrgstrukturDataTable
    3. Get
    4. Return _dtOE
    5. End Get
    6. Set(ByVal value As dsMA_Rechner.tbl_OrgstrukturDataTable)
    7. _dtOE = value
    8. End Set
    9. End Property
    10. Public Sub AufbautvwOE()
    11. Me.tvwOE.Nodes.Clear()
    12. Dim dtrowsOE() As dsMA_Rechner.tbl_OrgstrukturRow
    13. Dim node As TreeNode
    14. Dim nodes As TreeNode()
    15. Dim subNode As TreeNode
    16. Dim dtrowOE As dsMA_Rechner.tbl_OrgstrukturRow
    17. dtOE.DefaultView.Sort = dtOE.ID_OrgEbeneColumn.ColumnName.ToString & "," & dtOE.SortColumn.ColumnName.ToString
    18. dtrowsOE = DirectCast(dtOE.Select("ID_Orgstruktur>0", dtOE.ID_OrgEbeneColumn.ColumnName.ToString), dsMA_Rechner.tbl_OrgstrukturRow())
    19. Me.DataGridView1.DataSource = dtOE
    20. For Each dtrowOE In dtrowsOE
    21. If dtrowOE.IsuebergeordnetNull Then
    22. node = New TreeNode
    23. node.Name = "OE#" & dtrowOE.ID_Orgstruktur.ToString
    24. node.Text = dtrowOE.OrgStruktur
    25. Me.tvwOE.Nodes.Add(node)
    26. Else
    27. nodes = Me.tvwOE.Nodes.Find("OE#" & dtrowOE.uebergeordnet.ToString, True)
    28. If nodes.Count > 0 Then
    29. node = nodes.First
    30. subNode = New TreeNode(dtrowOE.ID_Orgstruktur.ToString)
    31. subNode.Name = "OE#" & dtrowOE.ID_Orgstruktur.ToString
    32. subNode.Text = dtrowOE.OrgStruktur.ToString
    33. node.Nodes.Add(subNode)
    34. Else
    35. MessageBox.Show("übergeordneter Knoten zu " & dtrowOE.OrgStruktur.ToString & " ID=" & dtrowOE.ID_Orgstruktur & " abhängig von " & dtrowOE.uebergeordnet & " fehlt")
    36. Exit Sub
    37. End If
    38. End If
    39. Next
    40. Me.tvwOE.ExpandAll()
    41. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Schoofi“ ()

    Schoofi schrieb:

    am effektivsten
    machst Du das, indem Du genau das machst, was Du beschrieben hast, allerdings den TreeNode weglässt.
    Sortiere alle Datensätze nach dem 1. Kriterium.
    Sortiere alle Datensätze, deren 1. Kriterium gleich ist, nach dem 2. Kriterium.
    Feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    sieht iwie wüst aus. Ich hab neulich mit c# einen Treeview aus einer typDataTable befüllt:

    C#-Quellcode

    1. private void PopulateTreenodeCollection(AccountDts.AccountRow[] rows, TreeNodeCollection nodes) {
    2. foreach (var dr in rows) {
    3. TreeNode t = new TreeNode();
    4. t.Text = dr.Code + " - " + dr.Name;
    5. t.Name = dr.Code.ToString();
    6. t.Tag = dr;
    7. nodes.Add(t);
    8. PopulateTreenodeCollection(dr.GetAccountRows(), t.Nodes);
    9. }
    10. }
    Zum Aufruf musste halt zunächstmal die typDataRows in ein Array selecten, deren ParentAccount-Property nothing ist. Dieses Array dann an diese Methode übergeben und der Treeview wird rekursiv befüllt.

    Was das mit sortieren zu tun hat, weiss nicht. Natürlich kann man die typDatarow-Arrays auch sortieren wie man will.

    Aber vlt. bin ich auch auffm falschen Dampfer:
    Handelt es sich überhaupt um eine richtige Baumstruktur, also mit prinzipiell beliebig vielen Ebenen?
    Ja es ist eine typische Baumstruktur, abgebildet werden soll die Organisationsstruktur einer Abteilung. Leider ist die Verzeichnistiefe nicht überall gleich und de Unterstellungsverhältnisse sind auch in jedem AG anders. Deswegen ist die ID_Orgebene zwischengeschaltet, die zum einen zum Sortieren dient und deren Tabelle gleichzeitig die Bezeichnung innerhalb der Organisationsstruktur (Arbeitsgebiet, Team, Koorsdinationsbereich.... ) umfaßt.
    Der 2. Ordnungsbegriff ist die Rangfolge innerhalb des Zweiges, da sonst u.U. der Leiter der OE als letzter zu sehen ist obwohl er nach oben gehört.
    Im Anschluß werden dann noch die MA an die OEs angehängt, da bin ich aber noch dabei.

    @RodFromGermany habe ich Dich richtig verstanden, das ich am besten ein 2. Rowarray aufbauen soll das nach dem 1. Suchkriterium gefiltert und nach dem 2. Sortiert ist ?
    Wie meinst Du das mit dem Treenode weglassen ?

    Das Datagridview diente übrigens nur der Kontrolle und fliegt anschließend raus.
    Der

    Schoofi schrieb:

    Treenode
    hat mit der Sortierung nix zu tun.
    Wenn Du ihn nur zur Anzeige brauchst, klar, dann hab ich Dein Anliegen ggf. falsch verstanden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Eine Baumansicht habe ich schon.
    Mein Projekt entsteht quasi als Ablösung eines ehemaligen VB6 Programms, so das ich leider auch sofort mit einer gefüllten Datenbank einsteigen muß.
    Also muß ich mir auch schon um die Reihenfolge der Subnotes Gedanken machen.

    Schoofi schrieb:

    Reihenfolge der Subnotes
    Hast Du sdas Redesign nach .NET schon durch?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Schoofi schrieb:

    Eine Baumansicht habe ich schon.

    Ok, dann habich die Methode unterschätzt.
    Nu sag, wie die beiden Spalten heissen, dann gebe ich dir die magic CodeLine

    achnee - geht doch nicht.
    also mit deiner Befüllmethode krieg ichs doch nicht gebacken. Weil die ist ja drauf angewiesen, dass die Datarows in einer bestimmten Reihenfolge auftreten - da kann man natürlich nicht umsortieren.

    Also doch erstmal umstellen auf eine rekursive Befüllung.

    Schoofi schrieb:

    komplett neu auf
    Genau so. :thumbup:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Eben deshalb benötige ich ja die Sortierung nach der ID_Orgebene, das habe ich schon hinbekommen.
    Die 2. Sortierung nach der Spalte Sort fehlt mir.
    Schön wäre es in einem Aufwasch wie bei SQL "Order by ID_Orgebene,Sort"
    Die Spalten sind ID_Orgebene und Sort.
    Um die Typisierung auszunutzen hatte ich es so versucht

    dtOE.ID_OrgEbeneColumn.ColumnName.ToString & "," & dtOE.SortColumn.ColumnName.ToString


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Schoofi“ ()

    ah, jetzt habichs - vielleicht. Also stellst vom DefaultView die Sortierung schön ein, in der Schleife durchläufst du aber die nachwievor unsortierte DataTable.

    also probierma

    VB.NET-Quellcode

    1. Public Sub AufbautvwOE()
    2. Me.tvwOE.Nodes.Clear()
    3. Dim dtrowsOE() As dsMA_Rechner.tbl_OrgstrukturRow
    4. Dim node As TreeNode
    5. Dim nodes As TreeNode()
    6. Dim subNode As TreeNode
    7. dtOE.DefaultView.Sort = dtOE.ID_OrgEbeneColumn.ColumnName & "," & dtOE.SortColumn.ColumnName
    8. For Each drv As DataRowView In dtOE.DefaultView
    9. Dim dtrowOE = DirectCast(drv.Row, dsMA_Rechner.tbl_OrgstrukturRow)
    10. If dtrowOE.IsuebergeordnetNull Then
    11. node = New TreeNode
    12. node.Name = "OE#" & dtrowOE.ID_Orgstruktur.ToString
    13. node.Text = dtrowOE.OrgStruktur
    14. Me.tvwOE.Nodes.Add(node)
    15. Else
    16. nodes = Me.tvwOE.Nodes.Find("OE#" & dtrowOE.uebergeordnet.ToString, True)
    17. If nodes.Count > 0 Then
    18. node = nodes.First
    19. subNode = New TreeNode(dtrowOE.ID_Orgstruktur.ToString)
    20. subNode.Name = "OE#" & dtrowOE.ID_Orgstruktur.ToString
    21. subNode.Text = dtrowOE.OrgStruktur.ToString
    22. node.Nodes.Add(subNode)
    23. Else
    24. MessageBox.Show("übergeordneter Knoten zu " & dtrowOE.OrgStruktur.ToString & " ID=" & dtrowOE.ID_Orgstruktur & " abhängig von " & dtrowOE.uebergeordnet & " fehlt")
    25. Exit Sub
    26. End If
    27. End If
    28. Next
    29. Me.DataGridView1.DataSource = dtOE
    30. Me.tvwOE.ExpandAll()
    31. End Sub
    ist natürlich ungetestet

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()