sorting arrays

  • Thread starter Thread starter Keith G Hicks
  • Start date Start date
K

Keith G Hicks

Geeze. I just remembered that there might not be a built in function to sort
an array in MS Access. Is that true? (foxpro has had it forever). If not, is
bubble sort code best way?

Thanks,

Keith
 
I found this if anyone's interested:

Sub ShellSortArray(a() As Variant)
Dim i As Long, j As Long
Dim Low As Long, Hi As Long
Dim PushPop As Variant
Low = LBound(a)
Hi = UBound(a)
j = (Hi - Low + 1) \ 2
Do While j > 0
For i = Low To Hi - j
If a(i) > a(i + j) Then
PushPop = a(i)
a(i) = a(i + j)
a(i + j) = PushPop
End If
Next i
For i = Hi - j To Low Step -1
If a(i) > a(i + j) Then
PushPop = a(i)
a(i) = a(i + j)
a(i + j) = PushPop
End If
Next i
j = j \ 2
Loop
End Sub
 
Geeze. I just remembered that there might not be a built in function to
sort
an array in MS Access. Is that true? (foxpro has had it forever). If not,
is
bubble sort code best way?

Well, the trick is that usually data comes form a table, or has to come form
"some" where. So, simply sort the data BEFORE it gets to the array!

Dim strSql As String
Dim rst As DAO.Recordset
Dim vArray As Variant

strSql = "select * from tblCustomers order by LastName"
Set rst = CurrentDb.OpenRecordset(strSql)
rst.MoveLast
vArray = rst.GetRows

So, the above results in a array dimensioned with all the columns for
fields,a nd also all records as rows in the array. And, as you can see...it
is sorted.
 
Those "somewhere's" are not always pre-sortable. Look at the bottom of the
Help on the Dir() function. You'll see the following:
Tip Because file names are retrieved in no particular order, you may want
to store returned file names in an array, and then sort the array.
 
Keith G Hicks said:
Those "somewhere's" are not always pre-sortable. Look at the bottom of
the
Help on the Dir() function. You'll see the following:
Tip Because file names are retrieved in no particular order, you may
want
to store returned file names in an array, and then sort the array.

Yes...without question, one does and need a handy sort rouinte.

I also have one in my bag of tricks..and amazing enough..it was the result
of usig the dir command!!

I can't say I used, or needed a sort of a arary much..but it dones come up
form time to time.

Because a list box, or a combo box can be stuffed with a vlue stirng of :


5;4;1

Then I make a sort rouinte to sort the above to:

1;4;5

The code to do this follows, and I used a simple insert merge sort. This
sort is less code, but it does make a copy of the data. Perahps I should
remove all the extra stuff..and just post a "clean" rouinte..but the
foolwing is arleady coded!!

Public Function strDSort(mytext As String, delim As String) As String

' This routine simply sorts a delimited string and retruns the result.
' This is NOT a high speed sort, but for listboxes etc that only have
' 100 or less elements, the sort delay time is not perceiable on a
' moderm pc today. This routine assumes non blank values

Dim intCount As Integer
Dim i As Integer
Dim SortBuf() As String
Dim strOne As String
Dim j As Integer
Dim iPoint As Integer

intCount = strDCount(mytext, delim)
If intCount = 0 Then
strDSort = mytext
Exit Function
End If

intCount = intCount + 1 ' One delinter actually means two values
abc;def is two values!

ReDim SortBuf(intCount) ' our results are sorted into this array.

For i = 1 To intCount
strOne = strDField(mytext, delim, i)
GoSub InsertOne
Next i

' now convert results back to a string

For i = 1 To intCount
If strDSort <> "" Then
strDSort = strDSort & delim
End If
strDSort = strDSort & SortBuf(i)
Next i

Exit Function



InsertOne:
' find place to insert
For j = 1 To intCount
If (strOne <= SortBuf(j)) Or (SortBuf(j) = "") Then
iPoint = j
Exit For
End If
Next j

' make a hole for the value by moving everthing down
For j = intCount To iPoint + 1 Step -1
SortBuf(j) = SortBuf(j - 1)
Next j
SortBuf(iPoint) = strOne
Return


End Function

Public Function strDField(mytext As String, delim As String, groupnum As
Integer) As String

' Returnds a group extract from a string via a delimter.
' Hence to grab "cat" from the string dog-cat you get:
' strDField("dog-cat","-",2)



Dim startpos As Integer, endpos As Integer
Dim groupptr As Integer, chptr As Integer

chptr = 1
startpos = 0
For groupptr = 1 To groupnum - 1
chptr = InStr(chptr, mytext, delim)
If chptr = 0 Then
strDField = ""
Exit Function
Else
chptr = chptr + 1
End If
Next groupptr
startpos = chptr
endpos = InStr(startpos + 1, mytext, delim)
If endpos = 0 Then
endpos = Len(mytext) + 1
End If

strDField = Mid$(mytext, startpos, endpos - startpos)

End Function

Private Function strDCount(mytext As String, delim As String) As Integer

' This routine simply returnds a count of a particular delim string.
' Note that delim can be more then one char, and thus we can use
' this for line couting in memo fields

Dim intPtr As Integer
Dim intFound As Integer
Dim delimLen As Integer

delimLen = Len(delim)

intPtr = InStr(mytext, delim)

Do While intPtr
intFound = intFound + 1
intPtr = intPtr + delimLen
intPtr = InStr(intPtr, mytext, delim)
Loop

strDCount = intFound


End Function
 
Hi,

well, there is an undocumented routine called SortStringArray from the Wizhook object that does that. For what I know it works in string arrays with only one dimension, and you have to be sure that every element in the array has at least an empty string (""). If not, Access will stop working (hang on, you say?). This is an example of use:

Dim SortArray(3) As String
Dim cnt As Integer

SortArray(0) = "Mary"
SortArray(1) = "John"
SortArray(2) = "Juan"
SortArray(3) = "Albert"

For cnt = 0 To 3
Debug.Print SortArray(cnt)
Next

WizHook.SortStringArray SortArray
Debug.Print

For cnt = 0 To 3
Debug.Print SortArray(cnt)
Next

but remember, this is an undocumented routine in a hidden object in Access.


Saludos,
Juan M Afan de Ribera
http://www.mvp-access.com/juanmafan
m
 
Back
Top