Re: Sorting variant array on multiple columns
- From: "RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx>
- Date: Sat, 13 Sep 2008 12:52:25 +0100
Wow where you'd dig that oldie up from ?
Yes, it was posted 11 years ago:
http://groups.google.co.uk/group/microsoft.public.vb.syntax/browse_frm/thread/6ce791e469df0229/0e96ecce282257ad?hl=en&lnk=st&q=Function+Sort2D#0e96ecce282257ad
Will have a look at your suggestions.
RBS
"Bill McCarthy" <Bill@xxxxxxxxxxxxx> wrote in message news:A43C06FB-4E84-4882-B96E-CC62D9CA9EFF@xxxxxxxxxxxxxxxx
Hi bart,
Wow where you'd dig that oldie up from ? In any case you can sometimes improve performance by doing single column bubble sort calls in the correct order (least important first), but that really depends on the level of duplicates. And hard coding the routine for a particular case may help too.
How much data are you dealing with, and what is the shape/types of the data ? If the majority of your data is strings, then swapping elements in VB6 causes copying of the strings. In this case you can improve performance by using a bubble sort that swaps the pointers around. See the code samples at this old article:
http://vb.mvps.org/articles/bb200007.asp
I think the routine in question is the one that sorts a list of files. Not you will need to change the path as by default it does all files on C drive which now crashes due to the listbox 32K of items being exceeded ;) But that does a bubble sort, compares the strings, and then swaps the pointers.
Likewise, having the data strongly typed will improve comparison operations dramatically.
"RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message news:O2PlaORFJHA.3288@xxxxxxxxxxxxxxxxxxxxxxxWas looking for a routine that sorts variant arrays on multiple columns and there isn't much available it seems.
I found one though posted by Bill McCarthy. Not sure if he wrote it. It seems to work fine, but it is somewhat slow
(actually not that much faster than my old method which was based on SQL on text files via ADO) and I wondered
if anybody had a fast routine available to do this job and would be willing to post it.
This is Bill's code (somewhat adapted, but only cosmetically):
Public Function Sort2DMultipleColumns(vArray As Variant, _
bHorizontal As Boolean, _
ParamArray SortIndex() As Variant)
'Explanation of arguments
'--------------------------------------------------------------------------------
'you need to specify the paramarray arguments in groups of three being for the
'column or row to sort by, then whether ascending or descending, then whether
'textual or binary sort.
'Repeat the ParamArray arguments for as many columns you want to sort in the
'appropiate order, eg:
'Sort a 2D array vertically by:
' column 1 descending binary
'then by column 3 descending textual,
'then by column 5 ascending binary use the following syntax:
'Sort2DMultipleColumns A(),False, 1, True, True, 3, True , False, 5 , False, True
'--------------------------------------------------------------------------------
Dim i As Long
Dim j As Long
Dim k As Long
Dim m As Long
Dim n As Long
Dim z As Long
Dim LB1 As Long
Dim LB2 As Long
Dim UB1 As Long
Dim UB2 As Long
Dim D
Dim lColOrRow() As Long
Dim bDescending() As Boolean
Dim bBinarySort() As Boolean
LB1 = LBound(vArray, 1)
LB2 = LBound(vArray, 2)
UB1 = UBound(vArray, 1)
UB2 = UBound(vArray, 2)
D = vArray
If UBound(SortIndex) < 0 Then
ReDim lColOrRow(0 To 0) As Long
ReDim bDescending(0 To 0) As Boolean
ReDim bBinarySort(0 To 0) As Boolean
lColOrRow(0) = 1
bDescending(0) = True
bBinarySort(0) = True
Else
ReDim lColOrRow(0 To UBound(SortIndex) \ 3)
ReDim bDescending(0 To UBound(SortIndex) \ 3)
ReDim bBinarySort(0 To UBound(SortIndex) \ 3)
For i = 0 To UBound(SortIndex) \ 3
lColOrRow(i) = SortIndex(i * 3)
bDescending(i) = SortIndex(1 + i * 3)
bBinarySort(i) = SortIndex(2 + i * 3)
Next i
End If
If bHorizontal Then
ReDim B(LB2 To UB2) As Long
ReDim C(LB2 To UB2)
For i = LB2 To UB2
B(i) = i
C(i) = vArray(lColOrRow(0), i)
Next i
TagSort C(), B(), LB2, UB2, bDescending(0), bBinarySort(0)
For i = LB1 To UB1
For j = LB2 To UB2
vArray(i, j) = D(i, B(j))
Next j
Next i
If UBound(lColOrRow) > 0 Then
For z = 1 To UBound(lColOrRow)
For i = LB2 To UB2 - 1
j = 1
Do While IIf(bBinarySort(n), vArray(lColOrRow(0), i) = _
vArray(lColOrRow(0), i + j), _
StrComp(vArray(lColOrRow(0), i), _
vArray(lColOrRow(0), i + j), _
vbTextCompare) = 0)
For n = 1 To z - 1
If bBinarySort(n) Then
If vArray(lColOrRow(n), i) <> vArray(lColOrRow(n), i + j) Then
Exit Do
End If
Else
If StrComp(vArray(lColOrRow(n), i), _
vArray(lColOrRow(n), i + j), _
vbTextCompare) <> 0 Then
Exit Do
End If
End If
Next n
j = j + 1
If i + j > UB2 Then
Exit Do
End If
Loop
If j > 1 Then
ReDim B(1 To j) As Long
ReDim C(1 To j)
For k = 1 To j
B(k) = k
C(k) = vArray(lColOrRow(z), i + k - 1)
Next k
TagSort C(), B(), 1, j, bDescending(z), bBinarySort(z)
ReDim D(LB1 To UB1, 1 To j)
For k = LB1 To UB1
For m = 1 To j
D(k, m) = vArray(k, i + m - 1)
Next m
Next k
For k = LB1 To UB1
For m = 1 To j
vArray(k, i + m - 1) = D(k, B(m))
Next m
Next k
i = i + j - 1
End If
Next i
Next z
End If
Else 'If bHorizontal
ReDim B(LB1 To UB1) As Long
ReDim C(LB1 To UB1)
For i = LB1 To UB1
B(i) = i
C(i) = vArray(i, lColOrRow(0))
Next i
TagSort C(), B(), LB1, UB1, bDescending(0), bBinarySort(0)
For i = LB1 To UB1
For j = LB2 To UB2
vArray(i, j) = D(B(i), j)
Next j
Next i
If UBound(lColOrRow) > 0 Then
For z = 1 To UBound(lColOrRow)
For i = LB1 To UB1 - 1
j = 1
Do While IIf(bBinarySort(0), vArray(i, lColOrRow(0)) = _
vArray(i + j, lColOrRow(0)), _
StrComp(vArray(i, lColOrRow(0)), _
vArray(i + j, _
lColOrRow(0)), vbTextCompare) = 0)
For n = 1 To z - 1
If bBinarySort(n) Then
If vArray(i, lColOrRow(n)) <> vArray(i + j, lColOrRow(n)) Then
Exit Do
End If
Else
If StrComp(vArray(i, _
lColOrRow(n)), _
vArray(i + j, _
lColOrRow(n)), _
vbTextCompare) <> 0 Then
Exit Do
End If
End If
Next n
j = j + 1
If i + j > UB1 Then Exit Do
Loop
If j > 1 Then
ReDim B(1 To j) As Long
ReDim C(1 To j)
For k = 1 To j
B(k) = k
C(k) = vArray(i + k - 1, lColOrRow(z))
Next k
TagSort C(), B(), 1, j, bDescending(z), bBinarySort(z)
ReDim D(1 To j, LB2 To UB2)
For k = 1 To j
For m = LB2 To UB2
D(k, m) = vArray(i + k - 1, m)
Next m
Next k
For k = 1 To j
For m = LB2 To UB2
vArray(i + k - 1, m) = D(B(k), m)
Next m
Next k
i = i + j - 1
End If
Next i
Next z
End If
End If 'If bHorizontal
Sort2DMultipleColumns = vArray
End Function
Private Function TagSort(C(), _
B() As Long, _
Low As Long, _
Hi As Long, _
Optional bDescending As Boolean, _
Optional bBinarySort As Boolean)
On Error Resume Next
Dim Low2 As Long
Dim Hi2 As Long
Dim MidValue
Dim Temp As Long
MidValue = C(B((Low + Hi) \ 2))
Low2 = Low
Hi2 = Hi
While (Low2 <= Hi2)
If bBinarySort Then
If bDescending Then
While (C(B(Low2)) > MidValue And Low2 < Hi)
Low2 = Low2 + 1
Wend
While (C(B(Hi2)) < MidValue And Hi2 > Low)
Hi2 = Hi2 - 1
Wend
Else
While (C(B(Low2)) < MidValue And Low2 < Hi)
Low2 = Low2 + 1
Wend
While (C(B(Hi2)) > MidValue And Hi2 > Low)
Hi2 = Hi2 - 1
Wend
End If
Else
If bDescending Then
While (StrComp(C(B(Low2)), MidValue, vbTextCompare) > 0 _
And Low2 < Hi)
Low2 = Low2 + 1
Wend
While (StrComp(C(B(Hi2)), MidValue, vbTextCompare) < 0 _
And Hi2 > Low)
Hi2 = Hi2 - 1
Wend
Else
While (StrComp(C(B(Low2)), MidValue, vbTextCompare) < 0 _
And Low2 < Hi)
Low2 = Low2 + 1
Wend
While (StrComp(C(B(Hi2)), MidValue, vbTextCompare) > 0 _
And Hi2 > Low)
Hi2 = Hi2 - 1
Wend
End If
End If
If (Low2 <= Hi2) Then
Temp = B(Low2)
B(Low2) = B(Hi2)
B(Hi2) = Temp
Low2 = Low2 + 1
Hi2 = Hi2 - 1
End If
Wend
If (Hi2 > Low) Then
TagSort C(), B(), Low, Hi2, bDescending, bBinarySort
End If
If (Low2 < Hi) Then
TagSort C(), B(), Low2, Hi, bDescending, bBinarySort
End If
End Function
RBS
.
- Follow-Ups:
- Re: Sorting variant array on multiple columns
- From: Bill McCarthy
- Re: Sorting variant array on multiple columns
- References:
- Sorting variant array on multiple columns
- From: RB Smissaert
- Re: Sorting variant array on multiple columns
- From: Bill McCarthy
- Sorting variant array on multiple columns
- Prev by Date: Re: How to get a file's title
- Next by Date: Re: Create an MS Access Table in VB6
- Previous by thread: Re: Sorting variant array on multiple columns
- Next by thread: Re: Sorting variant array on multiple columns
- Index(es):
Relevant Pages
|