sort order results

This forum is meant for questions and discussions about the X# language and tools
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

sort order results

Post by Karl-Heinz »

Note: i´m using a german windows. Within the system settings the selectable sort options are:
"phone book" or "dictionary"

If #windows collation is selected x# does a wrong "phone book" sort, while the "dictionary" sort seems to be ok. A #clipper collation seems to do a (wrong) "phone book" sort only ?

At the end of the msg the VO #windows and #clipper sort results are listed.

Code: Select all


// #DEFINE __CLIPPERSORT__	
FUNCTION DoSort() AS VOID 
LOCAL aSort AS ARRAY
LOCAL i AS DWORD

 
 
  // Default setting is #WINDOWS	


#ifdef __CLIPPERSORT__ 

   ? "#CLIPPER setting is used"
   ?	
    SetInternational( #CLIPPER) 
    setcollation( #clipper ) 
    
    
    IF ! setnatdll ( "german" )  
    	? "Error SetNatDll german"     	
    	
    ENDIF 
    
   SetDatecountry ( 5 )  // german 
   
#else 

   ? "#windows setting is used"
   ? 
    
#ENDIF 

 

   ? "SetInternational()" , SetInternational()   
   ? "SetCollation()" , SetCollation()   
   ? 

    aSort := { "Göthe" , "Goethe" , "Goldmann" , "Götz" , "Göbel"} 
    
    asort ( aSort )
    
    ? "------------"
    ? "Asort result" 
    ? "------------"

/*

    X# result: setinternational and Setcollation(#WINDOWS)  

    phone book (wrong)           Dictionary (ok)

    Göbel 		         Göbel
    Göthe   <--- swap            Goethe    
    Goethe  <--- swap            Goldmann
    Götz                         Göthe
    Goldmann                     Götz 
 

    X# result: Setinternational and SetCollation(#CLIPPER)
      + setnatdll ( "german")

    ( wrong, seems to do a (wrong) phone book sort only ?)  

    Göbel
    Göthe
    Goethe
    Götz
    Goldmann


*/
     
 

    FOR i := 1 UPTO alen ( aSort )
         ? aSort [ i ]
   		
   NEXT
   
   ? 
   ?
   ? "---------------------------"
   ? "List <STRING>{} sort result" 
   ? "---------------------------"
      
	VAR aList := List <STRING>{}
	
	                                 
	aList:add ( "Göthe" ) 
	aList:add ( "Goethe" )
	aList:add ( "Goldmann" )
	aList:add ( "Götz" )
	aList:add ( "Göbel" )
	
	aList:sort() 
 
 
	FOREACH VAR c IN aList 
 	
 		? c 
 	
	 NEXT	   
   
	RETURN 



The VO results: setinternational and Setcollation(#WINDOWS)

phone book:

Göbel
Goethe
Göthe
Götz
Goldmann


dictionary:

Göbel
Goethe
Goldmann
Göthe
Götz



The VO results: Setinternational and SetCollation(#CLIPPER)
+ German.dll

Goethe
Goldmann
Göbel
Göthe
Götz


regards
Karl-Heinz
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

sort order results

Post by Chris »

Hi Karl-Heinz,

Again thanks for the report and apologies for not looking into it earlier. Apparently the problem is in ASort(), due to a bug it does not make use of the collation etc settings when sorting by default. But by providing a codeblock, which forces the comparison to be made based on the collation settings as in:

ASort ( aSort , , , { |a,b| a<b } )

then I do get the same results as in VO, can you please confirm?

About the Phone Book/Dictionary system settings, can you please tell me where I can find those? For now for my tests I have simply changed my system locale of my (English) windows to German, but I don't see such option. <aybe it's only on plain German windows?

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

sort order results

Post by Karl-Heinz »

Hi Chris,

when you have switched to "German" language:

- Click Start, and then click "Systemsteuerung" ("control panel")

- Click "Zeit,Sprache und Region" ( "Date, Time, Language, and Regional Options.") and then "Region"

now the "Region" window should open:

- Select the "Formate" TabPage
- click the Button "Weitere Einstellungen"
- within the new window select the Tabpage "Sortierungen"

now you should see the sort combobox with the items:

"Telefonbuch (DIN)"
"Wörterbuch"



About your asort hint:

In the late afternoon I get the time to do some tests. I will contact you then

regards
Karl-Heinz
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

sort order results

Post by Karl-Heinz »

Hi Chris,


Did you find the sort combo ?

> ASort ( aSort , , , { |a,b| a<b } )

Using a codeblock makes no difference here.

The attached zip contains a Excel file that lists several "Lexikon" and "Telefonbuch" sort results. Also included in the
Excel file is a image that shows a table with the expected sort results. (*)


Used tools:

1. VO
2. Excel
3.1 x# aSort() with and without a codeblock.
3.2.x# List<string>

Commonly spoken: All "Lexikon" sortings are correct, but all tools - except VO - show the same problem with the "Telefonbuch" sort. It seems, that VO is able to fix Windows on the fly :huh: . Seriously, i don´t get it: The Question is, what does VO do to be able to create a correct "Telefonbuch" sortorder ?

regards
Karl-Heinz

(*) The 3th column "Österreichische Sortierung" ( Austrian sort ) shows the same sortorder as VO does when the #clipper setting and setnatdll ("German.dll") is used. BTW. The Image is part of a wiki article ( content in german only ) https://de.wikipedia.org/wiki/Alphabetische_Sortierung
Attachments
GermanWinSort.ZIP
(89.01 KiB) Downloaded 69 times
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

sort order results

Post by wriedmann »

Hi Karl-Heinz,

PMFJI,

Code: Select all

The Question is, what does VO do to be able to create a correct "Telefonbuch" sortorder ?
if you use the nation DLL in VO, then VO uses it's own comparison tables.
And since for a long time the development of VO was done by German speaking people, you can be sure they made sorting working correctly.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

sort order results

Post by Chris »

Hi Karl-Heinz,

No, unfortunately I did not see it, it's probably because my development PC is a Win7 one, and probably this option was added in Win 10 I guess. I have a machine with Win10, will try later.

I am very surprised you said it didn't work with the codeblock though, did you have in the app the /vo13 compiler option enabled and you were also using SetCollation( #clipper ) and SetNatDll ( "german" )?

As Wolfgang said, in this case it works in VO (and it also should work in X#) because then all string comparisons go through a specialized function which takes into account the language rules as specified in the nation settings file. It's just that ASort() requires special treatment for that to work and this was previously overlooked.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

sort order results

Post by Karl-Heinz »

Guys,

seems i need a break ... Is it really that hard to follow in what i did and what i did not ? i thought it´s clear that the
content of the excel document shows the sort results of a german windows which has the buildin sort options
"Telefonbuch" and "Lexikon". The "Telefonbuch" and "Lexikon" sort results are listed in the excel columns "Telefonbuch" and "Lexikon", and of course the x# and VO sorts are made with the Setting SetCollation (#WINDOWS), or does anybody see a filled excel column like "Clipper/SetNatDll" ? The red cells show cleary that only VO, of course with the Setting SetCollation (#WINDOWS) .......... , does a correct "Telefonbuch" sort. So i asked:

> The Question is, what does VO do to be able to create a correct "Telefonbuch" sortorder ?

Setcollation (#CLIPPER) and setnatdll() is a completely different story ! On sunday evening i´ll take a look and report back the Setcollation (#CLIPPER) and setnatdll() results ...

regards
Karl-Heinz
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

sort order results

Post by Chris »

Hi Karl-Heinz,

I am pretty sure VO does the same thing as the X#/vulcan runtime does for comparing strings, when SetCollation() == #WINDOWS, then it calls the WinAPI CompareString() function and this function takes care of the rest. (Okay, I will not say again what it does when SetCollation() == #CLIPPER :) ).

When sorting arrays, VO uses the same mechanism for the sorting, to decide which array element goes first etc etc. And here is the problem, in X#/vulcan all string comparisons follow the same rules/mechanism that VO uses, except when comparing strings via the ASort() function, this is a special case and in this case the comparisons are always made with the String.Compare() function, this is why ASort() gives different results in X# than in VO. It is just an oversight, relatively easy to fix.

About excel, sorry, I have absolutely no idea what mechanism it uses for its sorting. About the Sort() method of List<string>, I am also not sure what method it is using for the sorting, but most probably I guess it also calls String.Compare(), but possibly with different parameters than what the X#/vulcan runtime use.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

sort order results

Post by Karl-Heinz »

Hi Chris,

I think i know what happens, if

SetInternational( #CLIPPER)
setcollation( #clipper )

setnatdll ( "german" )

is used ....

ASort(codeblock) or check/uncheck the /vo13 setting has no effect, and the #clipper result is always either a #windows "Telefonbuch" or a #windows "Lexikon" sortorder ! This can quickly be verified with SetAppLocaleID(). With SetAppLocaleID() it´s possible to change directly the current #windows sortorder, without to dive in a system setting dialog.


SetAppLocaleID(MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), ;
SORT_GERMAN_PHONE_BOOK)) // "Telefonbuch"

// SetAppLocaleID(MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), ;
// SORT_DEFAULT)) // "Lexikon"


IMHO - currently the "german" sort code gets never called. It seems that currently the #clipper collation
always falls back to the current #windows collation setting ?

can you verify what i assume ?

Code: Select all


DEFINE SUBLANG_GERMAN                 :=  0x01    // German
DEFINE LANG_GERMAN                    :=  0x07
DEFINE SORT_GERMAN_PHONE_BOOK         :=  0x1     // German Phone Book order
DEFINE SORT_DEFAULT                  :=   0x0     // sorting default
FUNCTION DoNatDllGermanSort() AS VOID 
LOCAL aSort AS ARRAY 	
LOCAL i AS DWORD

/*

   // VO + german.dll: 
   
   Goethe
   Goldmann
   Göbel
   Göthe
   Götz
   
  
*/ 

 //  SetAppLocaleID(MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), ;
//        SORT_GERMAN_PHONE_BOOK))  // "Telefonbuch"

	SetAppLocaleID(MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), ;
        SORT_DEFAULT))    // "Lexikon"

  
    ? "Clippersort" 
	?
	
    SetInternational( #CLIPPER) 
    setcollation( #clipper )
    
    IF ! setnatdll ( "german" )  
    	? "Error SetNatDll german"     	
    	
    ENDIF 
     
    
   SetDatecountry ( 5 )  // "GERMAN" define in VO.  
     
   
   ? "SetInternational()" , SetInternational()   
   ? "SetCollation()" , SetCollation()   
   ?   
   
   aSort := { "Göthe" , "Goethe" , "Goldmann" , "Götz" , "Göbel"}          
   
   
   asort ( aSort )
   ? "ASort() results"
   ? "---------------"
   
    FOR i := 1 UPTO alen ( aSort )
         ? aSort [ i ]
   		
   NEXT 
   
/*
    The result is always either a "Lexikon" or a "Telefonbuch" sortorder

    SetAppLocaleID(SORT_DEFAULT)   SetAppLocaleID(SORT_GERMAN_PHONE_BOOK)
    "Lexikon"					   "Telefonbuch"	  

    Göbel             			   Göbel                         
    Goethe                         Göthe
    Goldmann                       Goethe
    Göthe                          Götz
    Götz                           Goldmann

*/     
   
   ?
   
   ASort(aSort,,, {|a, b| a <= b})
      
   ? "ASort( codeblock ) results"
   ? "--------------------------"               
   
    FOR i := 1 UPTO alen ( aSort )
         ? aSort [ i ]
   		
   NEXT 
   
/* 
    The result is always either a "Lexikon" or a "Telefonbuch" sortorder
  
    SetAppLocaleID(SORT_DEFAULT)   SetAppLocaleID(SORT_GERMAN_PHONE_BOOK)
    "Lexikon"					   "Telefonbuch"	  

    Göbel             			   Göbel                         
    Goethe                         Göthe
    Goldmann                       Goethe
    Göthe                          Götz
    Götz                           Goldmann


*/      

 
  ?
  ?
	
 RETURN 


regards
Karl-Heinz
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

sort order results

Post by Chris »

Hi Karl-Heinz,

The way it is now, no matter the runtime (international, collation, nation) or compiler (/vo13) settings, the ASort() function always use the standard .Net's method for comparing strings (String.Compare() method of the system classes) which only has to do with how MS has implemented it and nothing related to VO.

It is just a small oversight and it only affects ASort() specifically and should be fixed in tomorow's new build, please give it a test again with it when it gets out.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
Post Reply