I am trying to develop an app for a club in Excel and in registering members for a day I have developed a UserForm with two ListBoxes, the first containing all members and the second with members for the day.
The second ListBox adds the members into playing groups so the order of members is important. To be flexible, the order of members needs to able to changed, so the order that people arrive is not necessarily which group they will end up in.
I have written the app using two ADODB RecordSets behind the ListBoxes, and this where the main work about ordering the players occurs. Should be simple! However if the order of players is altered often enough, the .Sort fails to be applied and .MoveNext seems to move not to the next sorted value, but to the next value as if no sort had been applied.
I have written a small program which demonstrates this perplexing behaviour.
Option Explicit
Dim rs As ADODB.Recordset
Sub demo()
Set rs = New ADODB.Recordset
Dim i As Long
Dim num As Long
With rs
.Fields.Append "number", adInteger
.Fields.Append "Name", adVarWChar, 1
.Open
For i = 1 To 6
.AddNew Array("number", "name"), Array(i, Chr(64 + i))
Next
.MoveFirst
Debug.Print .GetString
moveup "d", 2
.MoveFirst
Debug.Print .GetString
.Sort = "Number"
.MoveFirst
.Find "name='" & "f" & "'"
!Number = !Number + 1
.MoveNext
!Number = !Number - 1
.Sort = "number"
.MoveFirst
Debug.Print .GetString
.Close
End With
Set rs = Nothing
End Sub
Sub moveup(c As String, step As Long)
With rs
.MoveFirst
.Find "name='" & c & "'"
!Number = !Number + step
.Move step
!Number = !Number - step
.Sort = "Number"
End With
End Sub
In this example you can see that the Debug.Print gives the following output
1 A
2 B
3 C
4 D
5 E
6 F
1 A
2 B
3 C
4 F
5 E
6 D
1 A
2 B
3 C
5 D
5 E
5 F
So the final .MoveNext moves from record 4 to record 6.
I have overcome it (I think) by not relying on .MoveNext, but by using .Find again for the next listed player in the ListBox and then having a routine that goes down the ListBox entries and checks that the numbering in the RecordSet is correct.
Has anyone else experienced this behaviour in RecordSets? Is there a way to overcome the issue? Is there a better way to organise the data rather than in a RecordSet?
Update:
I have found that I can save the recordset to a stream, then close and reopen the recordset loading the stream. This seems to reset the index so it behaves properly. the code I used was as follows:
Sub reopenrs()
Dim strm As New ADODB.Stream
rs.Save strm
rs.Close
rs.Open strm
strm.Close
Set strm = Nothing
End Sub
I called this sub in the main routine after the 'moveup 2 ' call.
So although the problem still remains this looks like an acceptable work around for me
"Is there a better way to organise the data rather than in a RecordSet?" - yes! it's Excel itself. Since your data is not in a database, you don't need to use Recordset to perform any task since all tasks can be solved in Excel.
Just put data on a worksheet and you can manipulate them the way you need including sort, find, and other operations.