Support Info abonnieren
per RSS Feed hier : VO Support Newsfeed
Support zu Visual Objects
Tipp des Monats für Februar 03

ASort und exakte Sortierung




Druckversion anzeigen: Druckversion
Wussten Sie schon... ?

...dass die ASort()-Funktion nicht immer so sortiert wie Sie es erwarten würden? Es sei denn, Sie verwenden die hier vorgestellte ASortExact()-Funktion.


Zunächst hier das Problem:
FUNCTION Start()
LOCAL a,b,c,d AS STRING
LOCAL aTest AS ARRAY
LOCAL i AS DWORD

a := "Mile" //diese Werte könnten ja auch aus einer DBF eingelesen sein!
b := "Mill"
c := "Mille"
d := "Miller"
aTest := {a,b,a,c,d,b,d,e}
ASort(aTest) // oder auch: ASort(aTest,,,{|x,y|x <=y})
FOR i:=1 UPTO ALen(aTest)
    ?? aTest[i]
NEXT
Inkey(0)
Folgendes Ergebnis erwarten Sie sicher auch (Sortierung gemäß Telefonbuch):
Mile, Mile, Mill, Mill, Mille, Mille, Miller, Miller
   
Und das ist das Ergebnis unseres Testprogramms (vielleicht auch geringfügig anders):
Mile, Mile, Mill, Mille, Miller, Mill, Miller, Mille
   
Fehler in ASort? Nein! ASort führt intern während der Sortierung mehrfach Stringvergleiche durch. Und genau da liegt das Problem. Bei Stringvergleichen haben Sie i.d.R. Einfluss auf die Art des Vergleichs, indem Sie sich für den exakten Vergleich mit == entscheiden oder für den einfachen Vergleich mit dem =-Operator. Sie können auch im ASort-Codeblock den Vergleichsoperator festlegen, z.B. {|x,y| x < y}. Allerdings birgt ein strenges kleiner (<) oder größer ( >) die Gefahr in sich, dass ASort() in einer Endlos-Schleife hängt. Deshalb ist immer dringend empfohlen auch das = zuzulassen, also {|x,y|x <=y}. Und genau dies ist der Standard-Codeblock, den ASort verwendet, wenn keiner angegeben ist. Und darin liegt auch die Ursache für obiges Problem.
   
Und hier ist die Lösung:
Verwenden Sie im obigen die folgende ASortExact()-Funktion
FUNCTION ASortExact(aTest,nStart,nCount,cbSort)
LOCAL lExact AS LOGIC
lExact := SetExact(TRUE)
ASort(aTest,nStart,nCount,cbSort)
SetExact(lExact)
RETURN aTest
   
Das Ergebnis ist jetzt so wie oben das erwartete Ergebnis dargestellt wurde.
SetExact(TRUE) erzwingt für Stringvergleiche immer auch die Berücksichtigung der Stringlängen,m.a.W. es wird ein Vergleich wie bei Verwendung von == erzwungen.
   
Dieser Tipp stammt von: Michael Wittmer aus unserem Support-Team
 
Schicken Sie uns Ihren eigenen Tipp des Monats per Email
Druckversion anzeigen: Druckversion

 

 

 

Letzte Änderung des Inhalts auf dieser Seite: 05.02.03