Reputation: 511
I am converting some old legacy Access code to SQL for our legacy program in which we create a report based on thousands of records worth of data. We use multiple recordsets to access varying records/tables. Previously (in access), we found the desired records in the recordset(s) using the Recordset.Seek function. Doing this gets us the data we want in a manner of seconds.
In converting this to work with SQL using the ADO Recordset instead of DAO, I found that most people recommended simply setting the recordset equal to a new recordset using a query that would return the desired records. This has been the most efficient way to do this so far, but this still takes up to 2 minutes to get the same data that took seconds in access.
I see that the ADO Recordset has a .seek function as well, but I am having trouble attempting to implement this to compare speed/accuracy. If this would be a better method, how do I create/set the Index of the recordset, and how do I know the name of the index?
Thank you!
Upvotes: 0
Views: 2939
Reputation: 11991
You can use Seek
only with server-side recordsets from JET OLEDB provider. You can test if Seek
is available on a recordset with something like rs.Supports(adSeek)
.
What I usually do with client-side recordsets is to build in-memory indexes "by hand" with a function like this:
Public Function InitIndexCollection( _
rs As Recordset, _
sFld As String, _
Optional Fld2 As String, _
Optional Fld3 As String, _
Optional ByVal HasDuplicates As Boolean, _
Optional RetVal As Collection) As Collection
Const FUNC_NAME As String = "InitIndexCollection"
Dim oFld As ADODB.Field
Dim oFld2 As ADODB.Field
Dim oFld3 As ADODB.Field
Dim vBmk As Variant
Dim pCol As Collection '-- IVbCollection that doesn't raise duplicate error on Add
Set RetVal = New Collection
With rs
If .RecordCount > 0 Then
On Error Resume Next
vBmk = rs.Bookmark
On Error GoTo 0
.MoveFirst
Set oFld = .Fields(sFld)
If LenB(Fld2) <> 0 Then
Set oFld2 = .Fields(Fld2)
End If
If LenB(Fld3) <> 0 Then
Set oFld3 = .Fields(Fld3)
End If
If HasDuplicates Then
On Error Resume Next
Set pCol = RetVal
If oFld2 Is Nothing Then
Do
pCol.Add .Bookmark, CStr(oFld.Value)
.MoveNext
Loop While Not .EOF
ElseIf oFld3 Is Nothing Then
Do
pCol.Add .Bookmark, CStr(oFld.Value) & "#" & CStr(oFld2.Value)
.MoveNext
Loop While Not .EOF
Else
Do
pCol.Add .Bookmark, CStr(oFld.Value) & "#" & CStr(oFld2.Value) & "#" & CStr(oFld3.Value)
.MoveNext
Loop While Not .EOF
End If
On Error GoTo 0
Else
If oFld2 Is Nothing Then
Do
RetVal.Add .Bookmark, CStr(oFld.Value)
.MoveNext
Loop While Not .EOF
ElseIf oFld3 Is Nothing Then
Do
RetVal.Add .Bookmark, CStr(oFld.Value) & "#" & CStr(oFld2.Value)
.MoveNext
Loop While Not .EOF
Else
Do
RetVal.Add .Bookmark, CStr(oFld.Value) & "#" & CStr(oFld2.Value) & "#" & CStr(oFld3.Value)
.MoveNext
Loop While Not .EOF
End If
End If
If Not IsEmpty(vBmk) Then
.Bookmark = vBmk
End If
End If
End With
Set InitIndexCollection = RetVal
End Function
Then you can seek with Bookmark
property fast like this
Dim rsItems As Recordset
Dim cIndex As Collection
Set cIndex = InitIndexCollection(rsItems, "Code")
...
'--- loop on other rs'
Do While Not rs.EOF
...
rsItems.Bookmark = cIndex(rs!ItemCode.Value) '--- this is seek'
...
rs.MoveNext
Loop
Upvotes: 3