Can I show the progress of ADO query ?

B

Bonnie

I use ADO to query SQL database which contains many records.
Can I show the progress in status bar like using querytables ?
 
J

Jake Marx

Hi Bonnie,
I use ADO to query SQL database which contains many records.
Can I show the progress in status bar like using querytables ?

Yes you can do this if you execute your query asynchronously. But you'll
have to sink the ADO Recordset's events using a class module. When opening
your recordset, you need to make sure you use a client-side cursor, and you
must pass in adAsyncFetch to the Options argument. This will allow for
asynchronous fetching of records.

There are FetchProgress and FetchComplete events for the Recordset object
that you can utilize to update the statusbar or your progress bar. Here's
some example code that should get you started:

'/STANDARD MODULE
'/--------------------------
Private mcRCStatus As CrsStatus
Dim mcn As ADODB.Connection
Dim mrs As ADODB.Recordset

Sub test()
Dim sSQL As String

Set mcRCStatus = New CrsStatus
Set mcn = New ADODB.Connection

mcn.Open "DSN=MyDSN"
Set mrs = New ADODB.Recordset

With mrs
.CursorLocation = adUseClient
sSQL = "SELECT COUNT(ProductID) FROM dbo.tblProducts"
.Open sSQL, mcn, adOpenForwardOnly, adLockReadOnly
If Not (.BOF And .EOF) Then
mcRCStatus.NumRecords = .Fields(0).Value
End If
.Close

Set mcRCStatus.rs = mrs

sSQL = "SELECT ProductID, ProductName FROM dbo.tblProducts"
.CursorLocation = adUseClient
.Open sSQL, mcn, adOpenForwardOnly, adLockReadOnly, _
adAsyncFetch Or adCmdText
End With
End Sub

Sub RSDone()
With mrs
If .State = adStateOpen Then
If Not (.EOF And .BOF) Then
Cells(1, 1).CopyFromRecordset mrs
End If
.Close
End If
End With

Set mrs = Nothing
mcn.Close
Set mcn = Nothing
End Sub

'/CLASS MODULE (name=CrsStatus)
'/---------------------------------------
Public WithEvents rs As ADODB.Recordset

Public NumRecords As Long

Private Sub rs_FetchComplete(ByVal pError As ADODB.Error, _
adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
Application.StatusBar = False
RSDone
End Sub

Private Sub rs_FetchProgress(ByVal Progress As Long, _
ByVal MaxProgress As Long, adStatus As ADODB.EventStatusEnum, _
ByVal pRecordset As ADODB.Recordset)
Application.StatusBar = CStr(Progress) & " records of " & _
CStr(NumRecords) & " retrieved (" & Format$(Progress / NumRecords, _
"0%") & ")"
End Sub


NOTES: I thought at first that I could use the MaxProgress parameter in the
FetchProgress event routine for the total records so that I could calculate
progress %. But this number incremented as new rows were fetched as well
(it stayed a bit ahead of Progress, but the end effect was that the %
complete slowed considerably as it approached 100%). Maybe if you have an
optimized query (uses index seek/scan instead of table scan), this number
will be accurate from the very beginning. Anyway, to avoid using
MaxProgress, I executed a query to get the recordcount (should be pretty
fast) and passed that value to the class before executing the "real" query.

MORE NOTES: You may want to trap for the user cancelling execution (see
Application.EnableCancelKey in help) so you can clean up your recordset and
connection objects.

Hope this helps!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top