fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1
  • 2

TOPIC: sort order results

sort order results 9 months 4 weeks ago #5926

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
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.

// #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

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #5987

  Chris's Avatar Chris Offline Posts: 1179
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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #5992

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
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

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6007

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
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 ) de.wikipedia.org/wiki/Alphabetische_Sortierung
Attachments:

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6008

  wriedmann's Avatar wriedmann Away Posts: 1573
Hi Karl-Heinz,

PMFJI,
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
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6016

  Chris's Avatar Chris Offline Posts: 1179
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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6023

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
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

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6024

  Chris's Avatar Chris Offline Posts: 1179
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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

Last edit: by Chris.

sort order results 9 months 3 weeks ago #6073

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
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 ?

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

Please Log in or Create an account to join the conversation.

sort order results 9 months 3 weeks ago #6075

  Chris's Avatar Chris Offline Posts: 1179
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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6119

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
Hi Chris

Build 2.0.0.5

Congratulations !

If the /vo13 switch is set, asort () - with and without a codeblock - shows now the same sort order as VO. No matter if the setting is #Windows or #clipper.

well done !

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6120

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
Hi Chris,

I also tried "german2", and the "ASCII" sort is correct.

aSort := { "Übel", "Österreich" , "Ärger" , "Göthe" , "Goethe" , "Goldmann" , "Götz" , "Göbel"}

Goethe
Goldmann
Göbel
Göthe
Götz
Ärger
Österreich
Übel

i´m impressed !

BTW. is there anybody out there who ever used the german2.dll in VO ?

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6121

  robert's Avatar robert Offline Posts: 1001
Karl-Heinz,

Thanks for the feedback.
I am glad it works.
So can we expect your order for a FOX subscription soon <g>.

Robert

PS:
Did you also try the SetCollation(#Unicode). It should behave the same as SetCollation(#Windows) but should be somewhat faster and should also sort characters that are not in your Ansi codepage
XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6122

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
Hi Robert,

yes, collation #UNICODE and collation #WINDOWS sort orders are equal.
But it´s a little bit hard to detect the time differences with 8 items only ;-)

setinternational (#windows)
setcollation #unicode or #windows
"Lexikon"

Ärger
Göbel
Goethe
Goldmann
Göthe
Götz
Österreich
Übel


setinternational (#windows)
setcollation #unicode or #windows
"Telefonbuch"

Ärger
Göbel
Goethe
Göthe
Götz
Goldmann
Österreich
Übel

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6124

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
Hi Chris and Robert,

something is working not correctly ....

setinternational ( #clipper)
setcollation ( #clipper )
setnatdll ( "german" )

i enhanced in the afternoon my sort array to have some more Umlaute: "Übel", "Österreich" and "Ärger" to test "german2" which sorts correctly.

aSort := { "Übel", "Österreich" , "Ärger" , "Göthe" , "Goethe" , "Goldmann" , "Götz" , "Göbel"}

but now, when i switch back to the x# "german" setting the result is the same result the VO german2.dll and x# "german2" gives ?


VO german2.dll + x# "german2" and currently x# "german" too.

Goethe
Goldmann
Göbel
Göthe
Götz
Ärger
Österreich
Übel


i´m not able to get with x# "german" this sort order:

VO german.dll

Ärger
Goethe
Goldmann
Göbel
Göthe
Götz
Österreich
Übel


- from Goethe upto Götz it´s always correct.

- setnatdll ( "german" )
? setnatdll() == "german"

- setnatdll ( "german2" )
? setnatdll() == "german2"


regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6125

  Chris's Avatar Chris Offline Posts: 1179
Hi Karl-Heinz,

Thanks, I also see the problem. Maybe the char weights are not correct, will have a look and will get back to you.

Chris
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6129

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
very nice is the new runtimestate property "CompilerOptionVo13"

instead of setting the corresponding compiler switch in the IDE it´s now possible to set the VO compatible string comparison at runtime. The best place to do that is in the startup of the app where you set the general environment:

e.g.

setinternational ( #CLIPPER)
setcollation ( #CLIPPER )
setnatdll ( .... )
...
runtimestate:CompilerOptionVo13 := TRUE
...

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6131

  Chris's Avatar Chris Offline Posts: 1179
Hi Karl-Heinz,

That was supposed to be undocumented :)

It's not exactly like that, though, this is only used so that the runtime is aware of the state of the option. The compiler itself still only knows the option passed to it at compile time, so the code generation will be based on what you had selected when compiling.

To see what I mean, please just compile this with /vo13 disabled:

FUNCTION Start( ) AS VOID
LOCAL c1,c2 AS STRING
LOCAL l AS LOGIC
l := c1 < c2
RETURN

and look at tthe generated code with ILSpy, then recompile with /vo13 enabled and see the difference.

The first version uses String.Compare() for the comparison, while the second uses a X# runtime function, __StringCompare() and this is not affected of course if you change the runtimestate at runtime.

Well, we could probably always call __StringCompare() nd then this function would check for the status of the runtimestate property, but I don't think it's worth (slightly) harmong performance for that.

Chris
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6142

  Karl-Heinz's Avatar Topic Author Karl-Heinz Offline Posts: 269
Hi Chris,

> That was supposed to be undocumented

but it is, see whatsnew.rtf ;-)

[...]
Fixed a problem with string comparisons in runtime functions like ASort(). This now also respects the new runtime property CompilerOptionVO13 to control the sorting.
[...]

i see the IL differences in your sample and also, that e.g. a Asort() string comparison behaviour - no matter if compiled with /Vo13 checked or uncecked - can be changed at runtime. So the question is: why is it allowed to change the CompilerOptionVO13 setting from outside. Or, in which constellation is it safe to change this setting from outside ?

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

sort order results 9 months 2 weeks ago #6143

  robert's Avatar robert Offline Posts: 1001
Karl-Heinz,
There is no "right" answer here.
In VO all string comparisons were using the VO style string comparison and were therefore respecting the Collation and in case of Clipper collation were using the weight tables from the nation module.

In .Net we do not want to force that, because these string comparisons are limited to the Ansi/OEM character set only and do not cover the full unicode character set. Therefore inside the base classes/structures such as USUAL we cannot know what kind of comparison you want to do. So we added this option, that allows you to control the string comparisons.
What you should realize is that this is a GLOBAL setting. So if your app sets this then also string comparisons in other components created with the X# runtime will be affected. This is good and bad at the same time. It depends on how you see it.
We initialize the setting only when you compile your main app with X#. So if you only created DLLs with X# but your main app is a C# app then you have no choice but to set / change this in your code.
Otherwise I would probably just let the compiler handle things.
You should also realize that if you create a DLL with X# and enable the option for compatible string comparisons then all comparisons between strings or between strings and usuals will be affected. However string comparisons inside usuals depend on the global setting. So if your main app uses a different setting then results may not be what you expect.
So in general: use the same setting for all your DLLs and app.

Robert
XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

Last edit: by robert.
  • Page:
  • 1
  • 2