vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Brandneu! sevEingabe v3.0 - Das Eingabecontrol der Superlative!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: tamaleus
Datum: 17.03.14 03:46

Hallo gute «Geister»!

Ich habe hinter einem Datagridview eine Tabelle mit den vier Feldern "Titel", "STitel", "Text" und "Quelle", die ich neu sortieren will, was ich mit

dv_TArchiv.Sort = "TITEL Asc, STITEL Asc, TEXT Asc, QUELLE Desc"
mache und dann die Ansicht wieder als Quelle zuordne:

DataGridView1.DataSource = dv_TArchiv
Und schon hier, aber auch nachher, nach dem Speichern des Datagrids zeigt sich eine falsche Sortierreihenfolge. Und dies unabhängig davon, ob ich auf- oder absteigend und ob ich ein, zwei oder vier Felder sortiere. Anstatt der Sortierung in der Reihenfolge

0 < 1 < 5 < 9 < A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
erhalte ich immer etwas wie

! < ( < . < / < „ < « < 0 < 1 < 2 < 3 < A < À < A < a < A < B < b < B
und dies, obwohl ich die Optionen

Option Explicit On
Option Strict On
Option Compare Binary
gesetzt habe.

Meine Standard-Sprache ich "Deutsch (Schweiz)", mein Tastatur-Layout ist "Schweiz (deutsch)", meine Codepage ist gemäss Registry-Eintrag "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP" die 850, womit ich in DOS und WIN überall korrekte Sonderzeichen und Umlaute angezeigt bekomme. Das Ganze findet auf WinXP mit SP3, inkl allen Updates und VB.NET unter VBEE2010 statt. Und: "Ja, ich habe auch neuere Systeme, muss das aber auch auf XP am Laufen halten."

Merkwürdigerweise stimmt auch der Vergleich, wenn ich direkt prüfe, ob ?"A" = "a" ist. Dann erhalte ich FALSE, ebenso, wie wenn ich ?"A" = "à" abfrage. Und ?"A" < "a" ergibt bei mir TRUE, ebenso wie ?"A" > "9" TRUE ergibt.

Schlicht, die Sortierreihenfolge meiner Felder/Texte nach einem Binary Sort ist falsch und entspricht nicht der ASCII-Reihenfolge.

Woran könnte das liegen?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: Manfred X
Datum: 17.03.14 12:35

Hallo!

Diese Frage gehört in das Einsteigerforum von VB.Net !

Die "Option Compare"-Einstellung hat hier keine Wirkung.

Du kannst Deine Sortierung selbst verwalten:
http://msdn.microsoft.com/en-us/library/ms171608.aspx



Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: tamaleus
Datum: 18.03.14 23:12

Hallo

Sorry für das falsche Forum. Bin halt Anfänger in jeglicher Hinsicht!

Und danke für die Antwort. Allein, ich verstehe sie leider nicht.

Ich habe mir nun die angegebene Seite rauf und runter angesehen und alle drei Beispiele durch-exerziert, verstehe aber beim besten Willen nicht, wie ich nun zu einer Sortier-Reihenfolge in der Tabelle, bzw. dem Datagrid komme, die der Reihenfolge der ASCII-Codes entspricht.

Demnach kommt eben das grosse "A" (Alt-65) vor dem grossen "Z" (Alt-90) und das kleine "a" (Alt-97) kommt erst nach dem grossen "Z". Aktuell wird mir aber z.B. das sog. Gimet ("«", Alt-0171) noch vor dem grossen "A" einsortiert, was - zumindest in meinem Fall - falsch ist.

Wie/wo (am besten bitte! sehr konkret) stelle ich nun diese Sortierreihenfolge ein?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: Manfred X
Datum: 19.03.14 00:25

Du möchtest die sortierten Zeilen auch speichern?
In dem Fall könntest die Datenzeilen in der Tabelle über
einen eigenen Comparer sortieren lassen.

Hier ein Beispiel:

    Dim rndm As New Random 'Zufallsdaten
 
    'Für Übergabe des CustomComparers
    Delegate Function ComparerTTQDelegate _
                      (ByVal r1 As DataRow, r2 As DataRow) As Integer
 
    Dim myComparerTTQ As New ComparerTTQDelegate _
                      (AddressOf ComparerTitelTextQuelle)
 
 
    Public Sub XMain()
        'Testdaten erstellen  
        Dim dt As DataTable = FillTable()
 
        'Datensätze sortieren lassen 
        Dim dt_sorted As DataTable = _
             TableSort.SortedTable(dt, myComparerTTQ)
 
        'Datensätze in einem DatagridView (dgv) anzeigen
        dgv.DataSource = dt_sorted
    End Sub
 
 
    Public Function FillTable() As DataTable
 
        Dim dt As New DataTable
        With dt.Columns
            .Add("Titel")
            .Add("Text")
            .Add("Quelle")
        End With
 
        Dim titel, text As String
        For i As Integer = 1 To 20
            titel = CreateEntry()
            For k As Integer = 1 To 20
                text = CreateEntry()
                For l As Integer = 1 To 5
                    dt.Rows.Add(titel, text, CreateEntry)
                Next l
            Next k
        Next i
        Return dt
    End Function
 
 
    Private Function CreateEntry() As String
        Dim stb As New System.Text.StringBuilder
        Dim l As Integer = rndm.Next(3, 12)
        For i As Integer = 0 To l
            'Hier zu testende Bytefolgen ausgeben lassen
            Dim byt As Byte = CByte(rndm.Next(65, 91))
            stb.Append(Chr(byt))
        Next i
 
        Return stb.ToString
    End Function
 
    'Der Comparer für den Vergleich von je zwei Datenzeilen
    Public Function ComparerTitelTextQuelle _
        (ByVal r1 As DataRow, ByVal r2 As DataRow) As Integer
 
        'ASC
        If r1("Titel").ToString > r2("Titel").ToString Then Return 1
        If r1("Titel").ToString < r2("Titel").ToString Then Return -1
        'ASC
        If r1("Text").ToString > r2("Text").ToString Then Return 1
        If r1("Text").ToString < r2("Text").ToString Then Return -1
        'DESC
        If r1("Quelle").ToString > r2("Quelle").ToString Then Return -1
        If r1("Quelle").ToString < r2("Quelle").ToString Then Return 1
 
        Return 0
    End Function
Die Klasse für das Sortieren ...
''' <summary>Erstellt eine neue Datatable in sortierter Reihenfolge</summary>
Public Class TableSort
 
    Shared rndm As New Random(DateTime.Now.Millisecond)
 
    ''' <summary>Datensätze der Tabelle sortiert zurückgeben</summary>
    Public Shared Function SortedTable(ByVal Table As DataTable, _
        ByVal comparer As [Delegate]) As DataTable
 
        Dim l As Integer = Table.Rows.Count - 1
        Dim rows(l) As DataRow
        Table.Rows.CopyTo(rows, 0)
 
        QuickSort(comparer, rows, 0, l)
 
        Dim dt As DataTable = Table.Clone
        For i As Integer = 0 To rows.Length - 1
            dt.ImportRow(rows(i))
        Next i
        Return dt
    End Function
 
    ''' <summary>Sortierung der Datenzeilen durch Quicksort gemäß 
    ' CustomComparer</summary>
    ''' <param name="comparer">Delegate für CustomComparer</param>
    ''' <param name="rows">Referenzliste der zu sortierenden Rows</param>
    ''' <param name="First">erstes zu sortierendes Element in Rows</param>
    ''' <param name="Last">letztes zu sortierendes Element in Rows</param>
    Private Shared Sub QuickSort(ByVal comparer As [Delegate], _
                            ByVal rows() As DataRow, _
                            ByVal First As Integer, ByVal Last As Integer)
 
        Dim i, j, m As Integer
        Dim x As DataRow
        Dim rv_s As DataRow
 
        i = First : j = Last
        m = rndm.Next(First, Last + 1)
        x = rows(m)
 
        Do
            While CInt(comparer.DynamicInvoke({rows(i), x})) < 0
                i += 1
            End While
 
            While CInt(comparer.DynamicInvoke({rows(j), x})) > 0
                j -= 1
            End While
 
            If (i <= j) Then
                rv_s = rows(i)
                rows(i) = rows(j)
                rows(j) = rv_s
 
                i = i + 1 : j = j - 1
            End If
        Loop Until (i > j)
 
        If (First < j) Then QuickSort(comparer, rows, First, j)
        If (i < Last) Then QuickSort(comparer, rows, i, Last)
    End Sub
End Class


Beitrag wurde zuletzt am 19.03.14 um 00:26:49 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: tamaleus
Datum: 19.03.14 02:15

Erst mal vielen herzlichen Dank für die ganze Mühe mit meinem Problem!!!

Ich erachte das längst nicht mehr als selbstverständlich und bin schon leicht beschämt, einen solchen Aufwand zu verursachen und dies, zumal es mir immernoch nicht klar ist.

Verstanden habe ich soviel:

Ich habe ein neues Projekt erstellt und im Formular ein Datagridview namens "dgv" eingefügt. Ferner habe ich den Button1 ins Form1 eingefügt, wo ich auch den ersten Teil Deines Codes hinterlegt habe. Den zweiten Teil habe ich in eine neue Klasse eingefügt, dann den Debug-Modus gestartet und auf den Button geklickt, hinter welchen ich die Sub "XMain" gelegt habe.

Da das aber alles Grossbuchstaben sind (innerhalb der Grossbuchstaben läuft es schon richtig, d.h. die Sortierung von gross "A" bis und mit gross "Z" stimmt schon), habe ich dann noch ein paar Zeilen ("a", "b", "1", "«" usw.) manuell eingefügt und dann nach Spalte 1 sortiert. Und das liefert mir ein Ergebnis, welches ich gerne anders rum sortiert hätte. Die Spalte sollte also aufsteigend mit den Ziffern (0-9) beginnen (vorausgehend noch ein paar Sonderzeichen), da die die niedrigsten ASCII-Werte haben. Danach würden dann alle Grossbuchstaben (A-Z) und wiederum danach alle Kleinbuchstaben (a-z) (und dann wieder ein paar Sonderzeichen) folgen.

Es würde also beispielsweise so aussehen:

"Anfang" (beginnt mit """ = ASCII-34)
16.50 ab Paddington (beginnt mit "1" = ASCII-49)
37 Grad (beginnt mit "3" = ASCII-51)
99 Luftballons (beginnt mit "9 L" = ASCII-57, ASCII-32, ASCII-76)
99 alleine aufsteigende Luftballons (beginnt mit "9 a" = ASCII-57, ASCII-32, ASCII-97)
AAL (beginnt mit "AA" = ASCII-65, ASCI-65)
ABC kommt vor (beginnt mit "AB" = ASCII-65, ASCI-66)
Aal (beginnt mit "Aa" = ASCII-65, ASCII-97)
abc (beginnt mit "a" = ASCII-97)
«ABC» (beginnt mit "«A" = ASCII-171, ASCII-65)
«abc» (beginnt mit "«a" = ASCII-171, ASCII-97)
Änderung (beginnt mit "Ä" = ASCII-196)
Überlegung (beginnt mit "Ü" = ASCII-220)


Siehe auch http://www.wire5net.ch/ASCII_Sort.jpg

Und das bekomme ich einfach nicht hin. Sorry, anscheinend habe ich nicht nur ein Brett, sondern einen ganzen Balken vor dem Kopf.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: Manfred X
Datum: 19.03.14 05:14

Hallo!

Der Aufwand ist gering.
Ich glaube, ich habe begriffen, worauf es Dir ankommt.
Die DataView-Klasse beherrscht nur Standard-Sortierungen.
Verwende für die Sortierung der Datenzeilen in der Datatable
einen Comparer des folgenden Typs:
(Der Namespace "Microsoft VisualBasic" wird benötigt.)

    Public Function ComparerTitelTextQuelle _
        (ByVal r1 As DataRow, ByVal r2 As DataRow) As Integer
 
        'Hierarchisches Sortieren (Binär)
        Dim ret As Integer
        'ASC
        ret = StrComp(r1("Titel").ToString, r2("Titel").ToString, _
                     CompareMethod.Binary)
        If ret = 0 Then
            'ASC
            ret = StrComp(r1("Text").ToString, r2("Text").ToString, _
                         CompareMethod.Binary)
            If ret = 0 Then
                'Desc
                ret = -1 * StrComp(r1("Quelle").ToString, _
                     r2("Quelle").ToString, CompareMethod.Binary)
            End If
        End If
 
        Return ret 
    End Function
Wenn Du in der CreateEntry-Methode folgende Zeile abwandelst,
wird das Resultat deutlich:
    Dim byt As Byte = CByte(rndm.Next(48, 122))


Beitrag wurde zuletzt am 19.03.14 um 05:20:35 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Sortier-Reihenfolge falsch trotz "Option Compare Binary" 
Autor: tamaleus
Datum: 19.03.14 06:23

Hallo!

Heureka!

Ich hab bei mir sogar schon alles implementiert und getested: "Es" sortiert genau, wie es soll!!!

Allerdings musste ich doch den ersten Comparer nehmen, also den

    'Der Comparer für den Vergleich von je zwei Datenzeilen
    Public Function ComparerTitelTextQuelle _
        (ByVal r1 As DataRow, ByVal r2 As DataRow) As Integer
 
        'ASC
        If r1("Titel").ToString > r2("Titel").ToString Then Return 1
        If r1("Titel").ToString < r2("Titel").ToString Then Return -1
        'ASC
        If r1("Text").ToString > r2("Text").ToString Then Return 1
        If r1("Text").ToString < r2("Text").ToString Then Return -1
        'DESC
        If r1("Quelle").ToString > r2("Quelle").ToString Then Return -1
        If r1("Quelle").ToString < r2("Quelle").ToString Then Return 1
 
        Return 0
    End Function
Wichtig war aber die neue Zeile

Dim byt As Byte = CByte(rndm.Next(48, 122))
damit das Ganze auch in dem Umfang sichtbar wird, wie es halt benötigt wird. Denn erst mit den Sonderzeichen und den Kleinbuchstaben zusammen wird klar, wie sortiert wird. Das war nur innerhalb der Grossbuchstaben nicht erkennbar.

Bleibt mir, den Hut zu ziehen und mich recht herzlich für diese Lektion zu bedanken, auch wenn ich doch noch eine Weile brauchen werde, bis ich dann alles so wirklich verinnerlicht haben werde.

Also nochmals vielen herzlichen Dank für Deine Arbeit und Hilfsbereitschaft! Echt klasse!

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel