Mashew
10-02-2001, 07:01 AM
I am trying to sort a collection of filenames like Internet Explorer does. Since I am trying to keep my collection and a listbox insync, I want to sort the collection and then populate the listbox. If I use the listbox sort, I have to search the collection everytime a user clicks on a filename.
Any ideas?
Banjo
10-02-2001, 07:13 AM
Try searching the forums and the web in general for these sorting algorithms:
Quick sort
Bubble sort
Shell sort
Each has their own advantages and disadvantages, so pick one that suits you.
Mashew
10-02-2001, 08:44 AM
Thanks for the info, but I'm having trouble with the sort order (my fault). IE sorts special characters, like @,$,_, before letters, but ASCII and UNICODE only sort some of them before Capital letters and others before lowercase letters. I've tried forcing all caps or all lowercase, but this doesn't work.
For example; my sort produces this
$0043f95.wpx
15th Anniversary.bmp
1stboot.bmp
2 Pane Collage.bmp
2000 Calendar.bmp
32bitfax.ini
@xtemp.bmp
_delis32.ini
Active Setup Log.bak
Active Setup Log.txt
but IE produces this
$0043f95.wpx
@xtemp.bmp
_delis32.ini
15th Anniversary.bmp
1stboot.bmp
2 Pane Collage.bmp
2000 Calendar.bmp
32bitfax.ini
Active Setup Log.bak
Active Setup Log.txt
Notice the @ and _ sort before numbers, but in my sort they show up after numbers.
Thanks for all your help
Banjo
10-02-2001, 08:54 AM
Can you post your sort algorithm?
usetheforce2
10-02-2001, 07:45 PM
I think it is compare "textually" images/icons/smile.gif, by adding <font color=blue> Option Compare Text </font color=blue> at module level, this will set the comparison method "textually"
i've tried your sample data with a basic bubble sort and returned a list sorted in the order you're looking for.
<pre><font color=blue>Option Compare Text</font color=blue>
<font color=blue>Dim</font color=blue> strlist(9) <font color=blue>As String</font color=blue>
<font color=green>' get this order***********</font color=green>
<font color=green>'$0043f95.wpx</font color=green>
<font color=green>'@xtemp.bmp</font color=green>
<font color=green>'_delis32.ini</font color=green>
<font color=green>'15 th Anniversary.bmp</font color=green>
<font color=green>'1 stboot.bmp</font color=green>
<font color=green>'2 Pane Collage.bmp</font color=green>
<font color=green>'2000 Calendar.bmp</font color=green>
<font color=green>'32 bitfax.ini</font color=green>
<font color=green>'Active Setup Log.bak</font color=green>
<font color=green>'Active Setup Log.txt</font color=green>
<font color=green>' *************************</font color=green>
<font color=blue>Private Sub</font color=blue> Form_Load()
strlist(9) = "$0043f95.wpx"
strlist(5) = "@xtemp.bmp"
strlist(3) = "_delis32.ini"
strlist(7) = "15 th Anniversary.bmp"
strlist(8) = "1 stboot.bmp"
strlist(6) = "2 Pane Collage.bmp"
strlist(4) = "2000 Calendar.bmp"
strlist(2) = "32 bitfax.ini"
strlist(1) = "Active Setup Log.bak"
strlist(0) = "Active Setup Log.txt"
Me.AutoRedraw = <font color=blue>True</font color=blue>
<font color=blue>For</font color=blue> X = 0 <font color=blue>To UBound</font color=blue>(strlist())
Me.Print strlist(X)
<font color=blue>Next</font color=blue>
<font color=blue>Call</font color=blue> Bubble_Sort(strlist())
Me.Print
Me.Print "sorted"
Me.Print
<font color=blue>For</font color=blue> X = 0 <font color=blue>To UBound</font color=blue>(strlist())
Me.Print strlist(X)
<font color=blue>Next</font color=blue>
<font color=blue>End Sub</font color=blue>
<font color=blue>Public Sub</font color=blue> Bubble_Sort(<font color=blue>ByRef</font color=blue> numbers() <font color=blue>As String</font color=blue>)
<font color=blue>Dim</font color=blue> i <font color=blue>As Long</font color=blue> <font color=green>'<-- # of indexes</font color=green>
<font color=blue>Dim</font color=blue> P <font color=blue>As Long</font color=blue> <font color=green>'<-- # of passes through the array</font color=green>
<font color=blue>Dim</font color=blue> X <font color=blue>As Long</font color=blue>
<font color=blue>Dim</font color=blue> temp <font color=blue>As String</font color=blue>
i = <font color=blue>UBound</font color=blue>(numbers())
<font color=blue>Do While</font color=blue> P < i
<font color=blue>Do While</font color=blue> X < (i - P)
<font color=blue>If</font color=blue> numbers(X) > numbers(X + 1) <font color=blue>Then</font color=blue>
temp = numbers(X)
numbers(X) = numbers(X + 1)
numbers(X + 1) = temp
<font color=blue>End If</font color=blue>
X = X + 1
<font color=blue>Loop</font color=blue>
X = 0
P = P + 1
<font color=blue>Loop</font color=blue>
<font color=blue>End Sub</font color=blue>
</pre>
good luck:
"The crows seem to be calling his name, thought Caw." - Jack Handy
Mashew
10-03-2001, 12:34 PM
I'm sorting as I load the collection.
LoadDirAndFiles is doing the reading, while FindSortSpot returns the index to insert after.
Here it is:
Private Function LoadDirAndFiles() As Long
'This routine will read thru path and create two collections; one for files and one for folders.
Dim lpFindFileData As WIN32_FIND_DATA
Dim lFileHdl As Long
Dim sTemp As String
Dim lRet As Long
Dim strDir As String
Dim strPath As String
Dim posColl As Integer
On Error Resume Next
Set mcolFolders = Nothing
Set mcolFolders = New Collection
Set mcolFiles = Nothing
Set mcolFiles = New Collection
'// remove filename and extension from path and add *.*
strDir = FolderPath(mvarPath)
strPath = strDir & "*.*"
'// get a file handle
lFileHdl = FindFirstFile(strPath, lpFindFileData)
If lFileHdl <> -1 Then
Do Until lRet = ERROR_NO_MORE_FILES
'// if it is a directory
If (lpFindFileData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = vbDirectory Then
'Strip off null chars and format the string
sTemp = StrConv(StripTerminator(lpFindFileData.cFileName), vbProperCase)
' make sure it is not a reference
If sTemp <> "." And sTemp <> ".." Then
'add it to the tree view.
If mcolFolders.Count = 0 Then
mcolFolders.Add sTemp 'Add first item
Else
posColl = FindSortSpot(mcolFolders, sTemp)
If posColl > 0 Then
mcolFolders.Add sTemp, , , posColl 'Insert after position determined
Else
mcolFolders.Add sTemp, , 1 'Insert before position 1 (at the beginning)
End If
End If
End If
'// if it is a file
ElseIf (lpFindFileData.dwFileAttributes And FILE_ATTRIBUTE_NORMAL) = vbNormal Then
sTemp = StrConv(StripTerminator(lpFindFileData.cFileName), vbProperCase)
If sTemp Like mvarPattern Then
'add it to the tree view.
If mcolFiles.Count = 0 Then
mcolFiles.Add sTemp 'Add first item
Else
posColl = FindSortSpot(mcolFiles, sTemp)
If posColl > 0 Then
mcolFiles.Add sTemp, , , posColl 'Insert after position determined
Else
mcolFiles.Add sTemp, , 1 'Insert before position 1 (at the beginning)
End If
End If
End If
End If
'// based on the file handle iterate through all files and dirs
lRet = FindNextFile(lFileHdl, lpFindFileData)
If lRet = 0 Then Exit Do
Loop
End If
'// close the file handle
mvarFileInx = 0
mvarFolderInx = 0
lRet = FindClose(lFileHdl)
End Function
Private Function FindSortSpot(ByRef Coll As Collection, ByVal Item As String) As Integer
'This function will return an index to the spot after which the item is to be added.
'Routine assumes no identical values (sorting filenames)
'0 means add to the beginning
'coll.count means add to end
'collection must have at least one value in it.
With Coll
'Check if collection has 0 members - return 0
If .Count = 0 Then
FindSortSpot = 0
Exit Function
End If
'Check if collection has 1 member - return 0 or 1 depending on value
If .Count = 1 Then
If Item > .Item(1) Then
FindSortSpot = 1
Else
FindSortSpot = 0
End If
Exit Function
End If
' if item > coll(.count) then return coll.count
If Item > .Item(.Count) Then
FindSortSpot = .Count
Exit Function
End If
' if item < coll(front) then return 0
If Item < .Item(1) Then
FindSortSpot = 0
Exit Function
End If
'Set front to 1 and back to coll.count
Dim front As Integer
Dim back As Integer
Dim halfway As Integer
Dim loopcount As Integer
front = 1
back = .Count
loopcount = 0
'do
' if item > coll(back) then return back
' if difference between front and back is 2 or less, then position must be one or the other
' if item > coll((back+front)/2) then
' front = (back+front)/2
' else
' back = (back + front)/2
'loop if return not set.
Do
If Item > .Item(back) Then
FindSortSpot = back 'item should be added after back pointer
Exit Function
End If
If back - front < 2 Then
FindSortSpot = front 'item is not > back (from before), so must be after front
Exit Function
End If
halfway = (back + front) / 2 'split difference (binary sort)
If Item > .Item(halfway) Then
front = halfway
Else
back = halfway
End If
loopcount = loopcount + 1 'Guarantees no endless loop
Loop Until loopcount > .Count
End With
End Function
Mashew
10-03-2001, 12:38 PM
It was that simple. Option Compare Text worked! Thanks for all the help.
++
V
\_/
Mashew
10-03-2001, 12:39 PM
It was figured out for me. Thanks for the help.
++
V
\_/