[Solved] Sort accents in array: BubbleSortList doesn't

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
User avatar
Mr.Dandy
Posts: 427
Joined: Tue Dec 11, 2012 4:22 pm

[Solved] Sort accents in array: BubbleSortList doesn't

Post by Mr.Dandy »

Hello all,

Code: Select all

Sub Main
    GlobalScope.BasicLibraries.loadLibrary("MRILib")
    GlobalScope.BasicLibraries.loadLibrary("Tools")
    Dim sList as variant
    sList = array("è", "a", "é", "à", "ù", "u", "e" )
    sRet = BubbleSortList(sList)
    mri sRet
End Sub
Result is wrong with: a, e, u, à, è, é, ù
And should be: a, à, e, é, è, u, u

Any clue?
Last edited by MrProgrammer on Fri May 27, 2022 9:08 pm, edited 1 time in total.
Reason: Tagged ✓ [Solved] -- MrProgrammer, forum moderator
OpenOffice 4.1.12 - Windows 10
User avatar
RoryOF
Moderator
Posts: 34611
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Sort accents in array: BubbleSortList don't

Post by RoryOF »

They are sorted according to the character encoding. Programming to sort in any other order will keep you occupied over the holiday period!
 Edit: Details of a Python method at

https://stackoverflow.com/questions/109 ... -in-python 
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: Sort accents in array: BubbleSortList don't

Post by JeJe »

Asc("à") '= 224
Asc("e") '=101

So e is before à.

If you can't find a ready made solution in Basic its easy to modify a sort algorithm - you don't need to understand them - just find the place where it says something like

if word1 < word2

And substitute that for a call to your function which performs the test.

That could be going through each letter of the words and a select case statement for if its one of those accented ones and you tell it à is before e.(Edit: à is before anything except a and before that - is probably what you want - simple)

Not hard.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: Sort accents in array: BubbleSortList don't

Post by JeJe »

This page says

https://www.vbforums.com/showthread.php ... ve-Sorting
Accented characters may sort earlier or later depending on the language.
and gives an insertion sort using the Windows CompareStringEx() API function, which as you're on Windows, you can use too.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: Sort accents in array: BubbleSortList don't

Post by JeJe »

As OO's texttable sort gives the result you want you could use a hidden document with a table to do the sort. Clunky and slow but it would work...

(Edit: can't find a Calc function that sorts an array or gives the comparison you want. StrComp in OOBasic differs from StrComp in VBA here and doesn't eiher)
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: Sort accents in array: BubbleSortList doesn't

Post by JeJe »

The clunky but easy method using a hidden document

Code: Select all

sub testsortarray
	t=	array("è", "a", "é", "à", "ù", "u", "e" )
	t=sortarray(t)
	for i = 0 to ubound(t)
		st =st &  t(i) & chr(10)
	next
	msgbox st
end sub


function sortArray(byval arr)

	Dim mArgs(0) as New com.sun.star.beans.PropertyValue
	dim doc,otext,i as long,sd,en
	mArgs(0).name= "Hidden"
	mArgs(0).value = true

	Doc=StarDesktop.loadComponentFromURL("private:factory/swriter","_blank",0,mArgs())
	otext = doc.text
	otext.string = ""
	tc =otext.createtextcursorbyrange(otext.getstart)
	for i= 0 to ubound(arr)
		tc.string =arr(i)
		tc.collapsetoend
		if i<> ubound(arr) then oText.insertControlCharacter( tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
	next
	tc =otext.createtextcursorbyrange(otext)
	sd= tc.createsortdescriptor
	tc.sort sd
	i= 0
	en= otext.createenumeration
	do while en.hasmoreelements
		p = en.nextelement
			arr(i)=p.string
			i = i+1
	loop
	doc.close false
	sortarray = arr
End function

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
JeJe
Volunteer
Posts: 2779
Joined: Wed Mar 09, 2016 2:40 pm

Re: Sort accents in array: BubbleSortList doesn't

Post by JeJe »

A more complete version which allows use of some other XSortable options - descending, sort by columns

Code: Select all



REM  *****  BASIC  *****



sub testsortarray2
'TEST PREFIXES LENGTH OF STRING AND COLUMN MARKIER TO STRINGS, 
'SORTS BY LENGTH IN ASCENDING ORDER (COLUMN1)
'AND THEN SORTS ORIGINAL STRING ((COLUMN2) IN DESCENDING ALPHANUMERIC ORDER

	t=	array("zebra","bats","aadvark","ant","goose","dog","cat","canary")

	for i = 0 to ubound(t)
		t(i) =len(t(i)) & chr(9) &  t(i)
	next

	'array,delimeter,IsSortAscending0, IsSortNumeric0, SortRowOrColumnNo0
	'IsSortAscending1, IsSortNumeric1, SortRowOrColumnNo1
	'IsSortAscending2, IsSortNumeric2, SortRowOrColumnNo2)


	t=sortarray2(t,chr(9),,true,1,false,,2)

	for i = 0 to ubound(t)
		st =st &  t(i) & chr(10)
	next
	msgbox st
end sub


function sortArray2(byval arr,optional delimeter as string,optional IsSortAscending0 as boolean,optional IsSortNumeric0,optional SortRowOrColumnNo0 as integer, _
	optional IsSortAscending1 as boolean,optional IsSortNumeric1,optional SortRowOrColumnNo1 as integer, _
	optional IsSortAscending2 as boolean,optional IsSortNumeric2,optional SortRowOrColumnNo2 as integer)

	Dim mArgs(0) as New com.sun.star.beans.PropertyValue
	dim doc,otext,i as long,sd,en,tc

	mArgs(0).name= "Hidden"
	mArgs(0).value = true

	Doc=StarDesktop.loadComponentFromURL("private:factory/swriter","_blank",0,mArgs())
	otext = doc.text
	otext.string = ""
	tc =otext.createtextcursorbyrange(otext.getstart)
	for i= 0 to ubound(arr)
		tc.string =arr(i)
		tc.collapsetoend
		if i<> ubound(arr) then oText.insertControlCharacter( tc, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False )
	next
	tc =otext.createtextcursorbyrange(otext)
	sd= tc.createsortdescriptor

	for i =0 to ubound(sd)

		select case  sd(i).name
		case "IsSortInTable"
		case "Delimiter"
			if ismissing(delimeter) = false then sd(i).value =asc( delimeter)
		case "IsSortColumns"
		case "MaxSortFieldsCount"
		case "SortFields"
			t=  sd(i).value

			with t(0)
				if ismissing(IsSortAscending0) = false then .IsAscending = IsSortAscending0
				if ismissing(IsSortNumeric0) = false then .FieldType =com.sun.star.table.TableSortFieldType.NUMERIC
				if ismissing(SortRowOrColumnNo0) = false then .field =SortRowOrColumnNo0
			end with
			with t(1)
				if ismissing(IsSortAscending1) = false then .IsAscending = IsSortAscending1
				if ismissing(IsSortNumeric1) = false then .FieldType =com.sun.star.table.TableSortFieldType.NUMERIC
				if ismissing(SortRowOrColumnNo1) = false then .field =SortRowOrColumnNo1
			end with
			with t(2)
				if ismissing(IsSortAscending2) = false then .IsAscending = IsSortAscending2
				if ismissing(IsSortNumeric2) = false then .FieldType =com.sun.star.table.TableSortFieldType.NUMERIC
				if ismissing(SortRowOrColumnNo2) = false then .field =SortRowOrColumnNo2
			end with

			sd(i).value=t
		end select
	next

	tc.sort (sd)
	i= 0
	en= otext.createenumeration
	do while en.hasmoreelements
		p = en.nextelement
		arr(i)=p.string
		i = i+1
	loop
	doc.close false
	sortarray2 = arr

end function




	'char
	'Delimiter 	contains the character that marks the separation of columns.
	'boolean
	'IsSortInTable 	determines if the content of a table is to be sorted.
	'long
	'SortRowOrColumnNo0 	contains the row or column index used in the first search key.
	'boolean
	'IsSortNumeric0 	determines if the sorting in the first search key is done numeric or alphanumeric order.
	'boolean
	'IsSortAscending0 	determines if the sorting in the first search key is done in ascending or descending order.
	'long
	'SortRowOrColumnNo1 	contains the row or column index used in the second search key.
	'boolean
	'IsSortNumeric1 	determines if the sorting in the second search key is done in numeric or alphanumeric order.
	'boolean
	'IsSortAscending1 	determines if the sorting in the second search key is done in ascending or descending order.
	'long
	'SortRowOrColumnNo2 	contains the row or column index used in the third search key.
	'boolean
	'IsSortNumeric2 	determines if the sorting in the third search key is done in numeric or alphanumeric order.
	'boolean
	'IsSortAscending2 	determines if the sorting in the third search key is done in ascending or descending order.
	'In
	'
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Sort accents in array: BubbleSortList doesn't

Post by hubert lambert »

Hi,

Here is an simple example with the XCollator interface:

Code: Select all

sub sortit
    sList = array("è", "a", "é", "à", "ù", "u", "e" )
    sRet = bubblesort_with_locale(sList)
    mri sRet
end sub

function bubblesort_with_locale(byval sortlist(), optional locale)
    REM load collator for given locale
    if ismissing(locale) then locale = thiscomponent.CharLocale
    collator = createUnoService("com.sun.star.i18n.Collator")
    collator.loadDefaultCollator(locale, 1)
    REM sort
    u = ubound(sortlist())
    sortvalue = 0
    for x = 1 to u- 1
        for y = 0 to u-x
            if collator.compareString(sortlist(y), sortlist(y+1)) = 1 then                             
                prov = sortlist(y)
                sortlist(y) = sortlist(y+1)
                sortlist(y+1) = prov    
            end if
        next y
    next x
    bubblesort_with_locale = sortlist()             
end function
Regards.
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
User avatar
karolus
Volunteer
Posts: 1159
Joined: Sat Jul 02, 2011 9:47 am

Re: Sort accents in array: BubbleSortList doesn't

Post by karolus »

viewtopic.php?f=21&t=56916
Tired of basic-bubblesort-developers
AOO4, Libreoffice 6.1 on Rasbian OS (on ARM)
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 7.6 flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
Post Reply