You are on page 1of 7

以 VBA 從關聯式資料庫中讀入資料

要從 VBA 連結並控制外部資料庫(Access、SQL Server、Oracle 等),必須使用 ADO(其為


ActiveX Data Object 的簡寫)。透過 ADO 不但可以匯入儲存於外部資料庫的資料(即查詢功能),也
可對資料庫作增加、刪除、修改紀錄等功能。
透過 ADO,使用者可以使用近似的程式碼(除了參數的修正外),存取不同的資料庫,其扮演了
資料庫的實際資料儲存與操作資料的應用程式間的仲介功能;如此,不管資料庫端如何變化,都不
會影響到程式端的編碼;因此可以說,ADO 是資料控制用的共通介面。
在 Excel VBA 中使用 ADO 之前必須先嵌入「ADO Library」,其作法為在 VBA 編輯器中,使用
「工具 設定引用項目」,帶出如圖 3.5.64 的「設定引用項目」視窗,於其中核取「Microsoft
ActiveX Data Objects 2.8 Library」選項(選擇最新版本的 ADO),如此即可於 VBA 中取用 ADO
的函式庫。

圖 3.5.64「設定引用項目」視窗

ADO 的物件模型如圖 3.5.65 所示。

Connection

Error

Command

Parameter

Recordset

Field

圖 3.5.65 ADO 物件模型


圖 3.5.65 模型中各物件功能簡單說明如下:

1. Connection:負責與資料庫的連線,也可用於不需要參數的 SQL 敘述。


2. Error:儲存與資料存取相關的錯誤。
3. Command:負責對資料庫查詢之處理。
4. Parameter:儲存參數查詢與預存程序(Stored Procedure)的參數
5. Recordset:儲存從資料庫取得之資料集(Recordset)
6. Field:儲存紀錄欄位資訊。

使用 ADO 控制外部資料庫的基本程序如下:

1. 取得與資料庫的連線(使用 Connection 物件)。


2. 對已經連線的資料庫進行處理。
3. 使用完後釋放連線。若不釋放連線,由於資料庫連結的排他處理,將造成他人無法使用。

以下以一實際例子來看如何以程式碼進行上述的處理。

[範例 3.28:以 VBA 讀取關聯式資料庫]

表 3.5.11 資料庫連線、處理與離線(連線釋放)之說明範例
行號 程式碼
1 Sub ADO_Ex1()

2 Dim D1101(100,6) As String


3 Dim Test_Dir As String
4 ‘設定資料庫路徑位置
5 Test_Dir = ThisWorkbook.Path & “\”
6 ‘連線資料庫
7 Dim Con_Test As ADODB.Connection
8 Set Con_Test = New ADODB.Connection
9 Con_Test.Open “Provider = Microsoft.Jet.OLEDB.4.0;” & “Data
Source=” & Test_Dir & “StockTrans.mdb”
10 ‘資料庫讀取
11 Dim RS_Test As ADODB.Recordset
12 Dim Row_No As Integer
13 Set RS_Test = New ADODB.Recordset
14 RS_Test.Open “1101D”, Con_Test
15 Row_No = 0
16 While RS_Test.EOF = False
17 Row_No = Row_No + 1
18 D1101(Row_No, 1) = RS_Test.Fields(“Date”)
19 D1101(Row_No, 2) = RS_Test.Fields(“Open”)
20 D1101(Row_No, 3) = RS_Test.Fields(“High”)
21 D1101(Row_No, 4) = RS_Test.Fields(“Close”)
22 D1101(Row_No, 5) = RS_Test.Fields(“Low”)
23 D1101(Row_No, 6) = RS_Test.Fields(“Volume”)
24 Cells(Row_No,1) = D1101(Row_No, 1)
25 Cells(Row_No,2) = D1101(Row_No, 2)
26 Cells(Row_No,3) = D1101(Row_No, 3)
27 Cells(Row_No,4) = D1101(Row_No, 4)
28 Cells(Row_No,5) = D1101(Row_No, 5)
29 Cells(Row_No,6) = D1101(Row_No, 6)
30 RS_Test.MoveNext
31 Wend
32 ‘資料庫連線釋放
33 RS_Test.Close
34 Con_Test.Close
35 Set Con_Test = Nothing
36 End Sub

為了表 3.5.11 程式碼的執行,我們必須準備一個名為 StockTrans.mdb 的資料庫,其中包含


不同資料表格, 名為 1101D 的資料表,儲存編號 1101 的股票的日資料,資料表格的設計如圖
3.5.66 所示,如圖 3.5.66 所示,1101D 的資料表包含 Date(日期)、Open(日開盤價)、High(日最
高價)、Close(日收盤價)、Low(日最低價)、Volume(日成交量)等總共 6 個欄位資料,所有欄位資料
均設定為文字格式,並依據該欄位儲存資料的可能數值範圍設定不同的欄位大小。

圖 3.5.66 資料表格設計

資料表設計完成後,即可輸入資料,逐筆輸入資料曠日費時,最好的方式是使用匯入資料的轉
方式。
首先,我們由將屬於編號 1101 股票的交易日期、開、高、收、低、量等資料匯整在一文字 中,該
文字檔以 Excel 打開如圖 3.5.67 所示。此彙整 案亦可藉由寫一 VBA 轉 程式產生。

圖 3.5.67 範例文字檔內容

然後,在 Access 中,使用功能表的「Office 按鈕 開啟舊檔」之功能,匯入資料,如圖 3.5.68


所示,記得檔案類型必須選取「文字檔」。即可進入如 圖3.5.69 的「匯入文字精靈」程序。

圖 3.5.68 開 舊 視窗
圖 3.5.69「匯入文字精靈」程序 I

在圖 3.5.69 中,選擇「分隔符號字元如到逗號或是 Tab 所分隔的欄位」選項,進到下一步,出


現圖 3.5.70 視窗。

圖 3.5.70「匯入文字精靈」程序 II

在圖 3.5.70 中選取逗號為分隔字元,進到下一步,使出現如圖 3.5.71 的視窗。

圖 3.5.71「匯入文字精靈」程序 III
在圖 3.5.71 中,由於我們已經事先定義好名為 1101D 的資料表,因此選擇「在現存的資料表
中」選項,並選取「1101D」選項。按下一步,進入圖 3.5.72 的視窗中,即可完成資料匯入之程序。

圖 3.5.72「匯入文字精靈」程序 IV

匯入完成後,打開 1101D 的資料表,即可出現如圖 3.5.73 的視窗。

圖 3.5.73 匯入文字檔後之結果

在備妥 StockTrans.mdb 的資料庫後,即可以執行表 3.5.11 的程式。表 3.5.11 中的程式碼說


明如下:

1. 行(1)為程序名稱,行(36)為執行程序的終點。
2. 行(2)宣告一名為 D1101 的陣列,用以儲存由資料庫讀入的資料,陣列第二維的大小為 6,依序
可以儲存日期與開高收低量等資料,由於承接的資料為文字資料,因此宣告陣列為字元陣列。
3. 行(3)宣告 Test_Dir 變數之變數型態,此變數用以儲存存 路徑。
4. 行(5)取得活頁簿 案所在路徑,以作為資料庫 案的預設路徑。也就是說,只要把資料庫 案與
此執行程序所在的活頁簿 案放在同一個目錄中,就不怕存取不到 案。
5. 行(6)到行(9)用以連線資料庫。行(7)將 Con_Test 宣告為 Connection 物件;在行(8)中使用
New 關鍵字產生新的 Connection 物件;在行(9)中對產生之 Connection 物件使用 Open 方法,
確立與外部資料庫的連線。行(9)的連線字串之基本格式如下:
Provider=<使用的 OLEDB Provider 名稱>; Data Source=<外部資料庫的 案位置>
代表性的 Provider 指定字串如表 3.5.12 所示。有些資料庫的連線字串參數更長,例如 SQL
Server 必須指定使用者名稱與密碼等。
6. 行(10)到行(31)為外部資料庫讀取程式碼。行(11)將變數 RS_Text 宣告為 Recordset 物件,並
於行(13)使用 New 關鍵字產生新的 Recordset 物件。行(12)宣告 Row_No 變數用以紀錄讀入資
料筆數。行(14)對所產生的 Recordset 物件,把想要匯入的資料表名稱與使用者連線指定為
Open 方法的引數,以便由連線資料庫(Con_Test)之指定資料表(名為 1101D)的資料讀入
Recordset 中。行(15)設定紀錄筆數的起始值。
7. 行(16)到行(31)的「While … Wend」迴圈用以將資料表的紀錄逐筆讀入陣列中,並顯示於工作
表上。行(17)用以增加資料紀錄筆數計數,行(18)至行(23)分別將日期、開、高、收、低、量等資料
讀入 D1101 陣列中的指定位置;指定讀入的欄位可以使用如下語法:
Recordset 物件.Fields(欄位名)
行(24)到行(29)將 D1101 陣列值存入試算表格位中,如此,即可以確知有無將資料成功讀入。
行(30)之 MoveNext 方法用以將資料表讀取紀錄指標移到下一筆紀錄,如此即可於下一次迴圈
中讀入下一筆資料。除了 MoveNext 外,MovePrevious、MoveFirst、MoveLast 分別用以將紀
錄移到前一筆、第一筆,以及最後一筆。
8. 行(32)至行(35)之指令用於釋放資料庫連線。行(33)中的 Close 方法用以關閉資料庫,行(34)中
的 Close 方法用以關閉連線,行(35)用以丟棄已經不用的物件。

本範例的程式碼看似複雜,但其實讀者可以引用大部分的程式碼,而僅修改部分參數,
包括:(1)連接資料庫種類;(2)資料庫 案名稱及其所在路徑;(3)資料表名稱;(4)資料欄
位名稱等,即可。

表 3.5.12 代表性的 provider 指定字串


資料庫引擎 Provider 指定字串
Jet 4.0(Access 2000 以後) Provider = Microsoft.Jet.OLEDB.4.0
Jet 3.5(Access 97) Provider = Microsoft.Jet.OLEDB.3.51
SQL Server Provider = SQLOLEDB.1
Oracle Provider = MSDAORA.1
ODBC Provider = MSDASQL.1

除了以上方法可用以將指定資料庫的資料表中資料讀入程式中外,另一種方法是使用 SQL 敘述
取得資料。
透過 SQL 敘述取得資料可有更大的彈性,以程式交易為例,往往僅需要分析特定股票、特定期
間的資料,因此不需要把整個資料表讀入,如此不但可以節省儲存空間,也可以加快處理效率。關於
SAL 語法,在本節後文中有分類整理說明。
為此,在以下範例中,我們先設計一簡單介面(如圖 3.5.74 所示),取得所欲分析的股票代碼以
及分析期間的起始與終止日期。繼而在 CommandButton1 的 Click 事件程序中撰寫如表 3.5.13 的
程式碼,即可達成目標。

You might also like