FetchProgress 事件可为您提供对记录集可用于向用户显示进度指示器的当前状态的信息。
完成记录集时激发 FetchComplete 事件加载。
更多信息
系统必备组件
- FetchProgress 和 FetchComplete 事件在 MDAC 2.5 或更高版本中只工作正常。 您可以从下面的 Microsoft 网站下载最新版本的 Microsoft 数据访问组件:
Microsoft Data Access Components (http://msdn.microsoft.com/library/default.asp?url=/downloads/list/dataaccess.asp)
- 如果您正在开发中 Microsoft Visual Studio 6.0 应用程序,您必须具有 service pack 3 或更高版本已安装。 您可以安装最新的 service pack,Microsoft Visual Studio 6.0 为从下面的 Microsoft 网站:
Visual Studio Product Updates (http://msdn.microsoft.com/vstudio/downloads/updates.asp)
编码要求
- 当您打开记录集时,您必须为记录集选项指定 adAsyncFetch。
- 您必须使用客户端游标,因为由 ActiveX 数据对象 (ADO) 客户端游标引擎返回 FetchProgress 和 FetchComplete 事件。
- 在 Visual Basic 必须声明在模块级别用 WithEvents 关键字使用 Dim Recordset。
属性
有两个影响 ADO 的异步行为的记录集属性。 应能打开记录集之前设置这些属性。
- 提取的初始大小 决定之前创建异步线程同步被提取多少条记录。 这允许小型的记录集,以创建无需创建一个线程的额外开销。 默认情况下,这是设置为 50。 若要保证称为 FetchProgress 和 FetchComplete,请将此值设置为 0。
- 背景抓取大小 确定多少条记录被提取到 FetchProgress 事件调用之间。 默认情况下,这是设置为 15。
事件
FetchProgress
FetchProgress 具有四个参数:
- 进度 是当前记录集中的记录数。
第一次调用 FetchProgress,进度是等于初始提取大小加上背景抓取的大小。 对于每个附加的调用进度等于以前的值加上背景抓取大小。 - MaxProgress 是要返回预期的最大值。
MaxProgress 不等于实际将返回的记录数。 ADO 具有提取记录以获取此值。 这意味着 MaxProgress 以往任何时候都只是最佳猜测。 MaxProgress 通常等于进度加上背景抓取的大小。
FetchProgess 始终调用 FetchComplete 之前调用。 在这种情况下进度和 MaxProgress 是为彼此相等。 此 MaxProgress 等于实际的检索的记录数。 - adStatus 的值确定是否发生了任何错误。 此值通常是 adStatusOK。
您可能会通过 adStatus 的值设置为值 adStatusUnwantedEvent 禁用 FetchProgress 事件。 - pRecordset 是对该记录集本身的引用。
FetchComplete
FetchComplete 具有三个参数:
- 如果 adStatus adStatusErrorsOccurred,您可以检查以确定发生了什么错误 pError。 如果您的代码调用 Cancel 方法执行查询之前,可能会发生这种情况例如执行。
- adStatus 的值确定是否发生了任何错误。
您可能会通过 adStatus 的值设置为值 adStatusUnwantedEvent 禁用 FetchComplete 事件。 - pRecordset 是对该记录集本身的引用。
示例代码
下面的示例演示如何使用 Visual Basic 中的 FetchProgress 和 FetchComplete 事件。
该示例使用名为 Pubs 一个 ODBC 数据源连接到附带 SQL Server 的 Pubs 数据库。
- 在 Microsoft Visual Basic,创建新的 标准 EXE。 默认情况下,Form1 添加到项目。
- 在 项目 菜单上单击选择 引用,然后选择 Microsoft ActiveX 数据对象库。
- 在 项目 菜单上单击以选择 组件,然后选择 Microsoft DataGrid 控件 6.0 (OLEDB)。
- 将一个 DataGrid、 一个 文本框 中和 命令按钮 拖到 Form1 上。
- 下面的代码添加到 Form1 的 代码 窗口:
Option Explicit Const strConn = "DSN=Pubs" Const strDefaultSQL = "SELECT * FROM Titles" Dim cn As ADODB.Connection Dim WithEvents rs As ADODB.Recordset Private Sub Form_Load() Command1.Caption = "Go" Text1.Text = strDefaultSQL Set cn = New ADODB.Connection cn.Open strConn End Sub Private Sub Command1_Click() Dim strSQL As String strSQL = Text1.Text Set rs = New ADODB.Recordset With rs .CursorLocation = adUseClient .Properties("Initial Fetch Size") = 2 .Properties("Background Fetch Size") = 4 Debug.Print "Start" Debug.Print "Initial Fetch Size: " & _ .Properties("Initial Fetch Size") Debug.Print "Background Fetch Size" & _ .Properties("Background Fetch Size") .Open strSQL, cn, , , adAsyncFetch End With End Sub Private Sub rs_FetchProgress(ByVal Progress As Long, _ ByVal MaxProgress As Long, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) Debug.Print "Fetch: " & Progress & _ " Max: " & MaxProgress End Sub Private Sub rs_FetchComplete(ByVal pError As ADODB.Error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) If adStatus <> adStatusOK Then Debug.Print "Failed" Debug.Print "Error: " & pError.Number & " - " & pError.Description Else Set DataGrid1.DataSource = pRecordset Debug.Print "Done" End If End Sub
- strConn 改为您的数据库有效的连接字符串和 strDefaultSQL 更改为有效的 SQL 查询从数据库返回的记录。
- 运行代码。 单击 搜索 按钮开始读取记录集。 在 视图 菜单上单击以选择 即时 窗口。 Visual Basic 立即窗口显示异步查询的进度。
*********************************************************
试了不行
下面的行
' WithEvents 關鍵字宣告物件類別的變數。
' 引發事件的物件稱作事件來源 (event source),來處理事件來源所引發的事件。
' WithEvnets 用來對應 ActiveX 物件所引發的事件。僅適用於物件類別模組。
' 您可以用 WithEvents 來個別宣告變數,但不可用來建立陣列,也不可與 New 同時使用。
Dim WithEvents cn As ADODB.Connection
Dim WithEvents Recordset物件 As ADODB.Recordset
Private Sub cn_ConnectComplete(ByVal pError As ADODB.Error, _
adStatus As ADODB.EventStatusEnum, _
ByVal pConnection As ADODB.Connection)
' 資料庫連線建立完成會觸發 ConnectComplete 事件
End Sub
Private Sub cn_Disconnect(adStatus As ADODB.EventStatusEnum, _
ByVal pConnection As ADODB.Connection)
' 中斷資料庫連線會觸發 Disconnect 事件
End Sub
Private Sub cn_ExecuteComplete(ByVal RecordsAffected As Long, _
ByVal pError As ADODB.Error, _
adStatus As ADODB.EventStatusEnum, _
ByVal pCommand As ADODB.Command, _
ByVal pRecordset As ADODB.Recordset, _
ByVal pConnection As ADODB.Connection)
' 當 Connnection 物件使用 Execute 方法執行 SQL 命令完成時會觸發 ExecuteComplete 事件
End Sub
Private Sub Form_Load() ' 表單載入事件
OpenCN ' 開啟資料庫連線
End Sub
Private Sub OpenCN() ' 開啟資料庫連線 ; Connection 的非同步執行
Dim strCN As String
' 因為使用 WithEvents , 所以必須再使用 New 關鍵字來建立一個物件類別的新執行個體
Set cn = New ADODB.Connection
' 資料庫連線字串
strCN = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:/XXOO/ABC.mdb;Persist Security Info=False"
With cn
'CursorLocation 屬性 , 設定或傳回資料指標服務的位置‧
'adUseClient 使用本端資料指標程式庫所提供的用戶端資料指標‧
' 本端資料指標服務通常具備多項驅動程式之資料指標所沒有的功能,
' 因此,就可以啟動的功能而言,使用這個設定值有其優點‧對於往後追溯相容性,
' 同義字的 adUseClientBatch 也受支援‧
'adUseServer 預設值‧使用資料提供者或驅動程式提供者所提供的資料指標‧
' 這些指標有時候具有很大的彈性,可容許他人對資料源所做的變更‧
' 然而,Microsoft Client Cursor Provider (例如不相關的 Recordset) 的某些功能,
' 無法用伺服端的資料指標來模擬,因而在這個設定值下不能使用這些功能‧
.CursorLocation = adUseClient
'adConnectUnspecified (預設值) 同步化建立連線。
'adAsyncConnect 非同步化建立連線。可以使用 ConnectComplete 事件來確定連線資料庫是否完成。
.Open strCN, , , adAsyncConnect
End With
'adStateClosed 資料庫連線狀態為關閉
'adStateOpen 資料庫連線狀態為開啟
Do Until cn.State = adStateOpen
' Do Loop 迴圈是為了等待資料庫連線建立完成
' 若無此迴圈 , 則程式將繼續往下執行 (資料庫連線會繼續非同步的執行建立),
' 而不等待資料庫的連線建立是否完成
DoEvents
Loop
End Sub
Private Sub OpenRS() ' 開啟資料錄(集) ; Connection 的非同步執行
' 常數 說明
' adCmdText 表示提供者會將 Source 評估為指令的文字定義。
' AdCmdTable 表示 ADO 會產生一個 SQL 查詢,從 Source 中指定的資料表傳回所有資料列。
' AdCmdTableDirect 表示提供者會從 Source 中指定的資料表傳回所有資料列。
' AdCmdStoredProc 表示提供者會將 Source 評估為一個預存程序。
' AdCmdUnknown 表示 Source 引數中未知的指令類型。
' AdCmdFile 表示保留的 (已儲存的) Recordset 會從 Source 中指定的檔案還原。
' AdAsyncExecute 表示 Source 作非同步執行。
' AdAsyncFetch 表示在 Initial Fetch Size 屬性中指定的初始數量被抓取後,剩下的資料列就會被非同步地抓取。
' 如果所需的資料列未被抓取,則會凍傷主要的執行緒,直到取得所需的資料列。
' AdAsyncFetchNonBlocking 表示在抓取時,絕不凍結主執行緒。
' 如果未抓取到所需的資料列,則目前的資料列會自動移到檔案的尾端。
Set Recordset物件 = Connection物件.Execute(SQL語法, , adAsyncExecute)
Do Until Recordset物件.State = 1 ' Recordset 的開啟(執行)狀態
DoEvents
Loop
End Sub
Private Sub Recordset物件_FetchComplete(ByVal pError As ADODB.Error, _
adStatus As ADODB.EventStatusEnum, _
ByVal pRecordset As ADODB.Recordset)
' 當非同步動作將所有的資料錄取至(傳入)Recordset 便會觸發此事件。
End Sub