| |
VB.NET - Ein- und UmsteigerRe: 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!
| |
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? | |
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
| |
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? | |
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. | |
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.
| |
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. | |
| 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 |
|
|
Neu! sevCoolbar 3.0
Professionelle Toolbars im modernen Design!
Mit sevCoolbar erstellen Sie in wenigen Minuten ansprechende und moderne Toolbars und passen diese optimal an das Layout Ihrer Anwendung an (inkl. große Symbolbibliothek) - für VB und MS-Access Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|