23. 資料庫的存取
本章將要介紹Visual Basic的內建報表產生功能以及幾個與資料庫相關的輔助精靈,這些輔助精靈可以幫你在很短的時間內建立起資料庫。另外,本章也要討論兩種使Visual Basic應用程式與資料庫結合的技術,第一種技術是利用資料控制項,第二種技術則是用資料存取物件(Data Access Objects,DAO)。
如何在資料庫發展過程中應用輔助精靈?
在發展資料庫時,利用Visual Basic和Access提供的工具,可以省下你大量的時間與精力。例如,Visual Basic提供了兩個輔助精靈,它們可以大大地簡化建立資料庫表單的工作;這些輔助精靈會建立一個由典型資料庫表單簡化而來的"陽春版"資料庫表單,雖說這種表單是"陽春版",它卻提供了大部分必備的功能,足夠讓你在設計資料庫應用程式時有個好的開始。
如果你打算要在Visual Basic應用程式中建立一個資料庫表單,可以使用應用程式精靈,它可以幫你省下大量的發展時間。如果要使用這個輔助精靈,請在「檔案」功能表中點選「建立新專案」,然後在「建立新專案」對話方塊中連續點選兩下「VB應用程式精靈」圖像。應用程式精靈除了會自動建立一些相關表單、功能表和其他應有的部分之外,應用程式精靈也會選擇性地加入一張資料庫表單到新的專案中。
在建立資料庫表單的過程中,如果想要掌握更細部的設計程序,你可以使用資料表單精靈;要使用資料表單精靈,請從「專案」功能表中選取「新增表單」,然後連續點選兩下「VB資料表單精靈」,資料表單精靈便會一步一步地引導你建立一張與資料庫相關聯的表單。
資料表單精靈提供三種基本表單供你選擇;第一種「單筆資料錄」表單一次顯示一筆資料表(Table)或查詢(Query)中的資料錄,第二種「方格」表單以方格資料工作表顯示所有資料錄,第三種「主要 / 明細」表單則從「主要」資料表中讀取一筆資料錄作為主資料錄,再從另一張資料表中讀取與主資料錄相關的所有資料錄,這些稱為明細資料錄,明細資料錄顯示在方格資料表中。我們用Visual Basic目錄下的BIBLIO.MDB和NWIND.MDB樣本資料庫作為說明的範例。資料表單精靈建立的「主要 / 明細」表單一次顯示一筆出版商的資料錄,而該出版商所出版的所有書籍全部都被列在下面的方格資料工作表中,如圖23-1。當你移動出版商資料錄到下一筆時,方格內的書籍資料錄也會跟著改變。
如果想要在更短的時間內建立起資料庫及資料庫表單,你可以用Access來建立和維護資料庫,然後用資料表單精靈來產生表單。在後面幾節裡,我們將會討論如何單獨由Visual Basic來完成資料庫以及資料表單的建立。
圖23-1 資料表單精靈所產生的「主要/明細」資料表單 |
如何使用資料控制項連結資料庫?
在Visual Basic的應用程式中使用資料控制項(Data Control)有兩個主要步驟:第一,建立資料庫;第二,建立使用者界面。
利用資料庫管理員建立資料庫
在下一節中,我們會討論如何利用程式建立資料庫,在這一節我們要介紹的是使用「資料庫管理員」增益功能建立資料庫的每一個步驟。
利用「資料庫管理員」建立資料庫的步驟如下:
圖23-2 在Brithdays資料表中加入資料欄 |
圖23-3 以「資料庫管理員」建立的BDAY資料庫 |
建立使用者界面
現在我們要為我們的資料庫建立一個使用者界面。建立一個標準執行檔,在Form1表單上加入三個控制項:文字方塊控制項txtName和txtBirthday,以及資料控制項datBDAY。為了美觀起見,你也可以加入幾個標籤控制項。圖23-4所顯示的是一張完成的表單。
圖23-4 使用資料庫控制項的「生日資料庫」應用程式執行的情形 |
使用資料控制項以及資料連結控制項(Data-Bound Control),主要的關鍵就是要正確地設定相關的屬性;第一個動作必定是把資料控制項的DatabaseName屬性設為資料庫的檔案名稱。在這個例子裡,要把DatabaseName設定為BDAY.MDB。接下來,把資料控制項的RecordSource屬性設定為Birthdays,這是資料庫控制項所引用的資料表名稱;一般而言,一個資料控制項通常會和一個資料表相互關聯。
在本例中,我們還有另一個資料控制項的屬性需要設定,才能使應用程式具備新增資料錄的能力。請將EOFAction屬性設為"2 - 新增一筆",這樣,當使用者移動資料錄到了最後一筆的空白資料錄時,若使用者在空白資料錄上輸入了資料,這筆資料錄就會被自動地新增至資料庫中。
資料控制項本身並不負責資料庫管理的工作,我們需要把資料控制項與其他控制項加以連結,我們稱這些控制項為資料連結控制項,資料連結控制項才是管理資料庫真正的工具。在本例中,我們要設定文字方塊的DataSource和DataField屬性,使文字方塊控制項成為與資料控制項datBDAY相關聯的資料連結控制項。現在,請將每個文字方塊控制項的DataSource屬性設為datBDAY,並且將每個文字方塊的DataField設定為資料庫中相對的資料欄名稱──把txtName的DataField屬性設為"Name",txtBirthday的DataField屬性設為"Birthday"。這些資料連結文字方塊控制項在連結了資料控制項之後,會提供下拉式的清單協助你設定DataSource和DataField,資料庫中可用的資料表和資料表中的欄位都會在這些清單裡。
執行應用程式
就是這麼簡單,你不需要寫任何程式碼就可以存取資料庫。現在執行這個應用程式,輸入名字和生日,然後點選資料控制項的下筆資料捲軸箭頭(向右的單箭號),這樣資料庫中就有了第一筆資料錄。
這個範例並不提供刪除和搜尋資料錄的功能,如果要加上這些功能,必須加入程式碼才行。
如何使用資料存取物件(DAO)來連結資料庫?
除了資料控制項之外,Visual Basic提供了資料存取物件(Data Access Objects,DAO)讓我們存取資料庫;在說明如何使用資料存取物件之前,先讓我們了解資料存取物件的組織結構。
資料存取物件
我們用一張資料存取物件的組織階層圖來說明資料存取物件,請看圖23-5。圖中的物件名稱若是複數,即含 (s),則表示這是個物件集合。例如Workspace(s) 表示這是個Workspace物件的集合,Workspace(0) 是集合中的第一個物件。圖23-5中只有DBEngine是單數,不是一個物件集合,整個Visual Basic資料存取物件的世界裡只有一個DBEngine。
下一小節中的範例程式使用了許多資料存取物件,當你在看這個程式時,請對照著圖23-5,這樣可以更了解資料存取物件。
以資料存取物件建立資料庫
以下這個簡短的程式是利用資料存取物件(不透過資料控制項)建立一個電話號碼資料庫,這個資料庫和前一節中的資料庫很相似,在本例中,我們用兩個文字資料欄存放資料,一個存放姓名,另一個存放電話號碼。
現在讓我們來建立這個資料庫。首先建立一個標準執行檔專案,在Form1中加入一個指令按鈕cmdCreate,把cmdCreate的Caption屬性設定為"Create"。請確定引用項目中已經包括了DAO程式庫;如果要引用DAO程式庫,請點選「專案」功能表中的「設定引用項目」,然後核取「Microsoft DAO 3.5.1 Object Library」。最後,在表單中加入下列的程式碼。
圖23-5 Visual Basic資料存取物件的結構 |
Option Explicit Private Sub cmdCreate_Click() `Create data access object variables Dim dbWorkspace As Workspace Dim dbDatabase As Database Dim dbTableDef As TableDef Dim dbName As Field Dim dbNumber As Field `Create data access objects Set dbWorkspace = DBEngine.Workspaces(0) Set dbDatabase = dbWorkspace.CreateDatabase( _ "C:\PHONES.MDB", dbLangGeneral) Set dbTableDef = dbDatabase.CreateTableDef("Phones") Set dbName = dbTableDef.CreateField("Name", dbText) Set dbNumber = dbTableDef.CreateField("Number", dbText) `Set field properties dbName.Size = 30 dbNumber.Size = 30 `Append each field object to its table object dbTableDef.Fields.Append dbName dbTableDef.Fields.Append dbNumber `Append each table to its database dbDatabase.TableDefs.Append dbTableDef `Close completed database dbDatabase.Close MsgBox "Database Created", , "Create Phones" End Sub
圖23-6所顯示的是本例執行的情形,只要按下「建立資料庫」按鈕就可以建立一個新的資料庫了。
這個程式所執行的動作可概述如下:前半部的程式碼宣告變數,資料存取物件產生之後被指定給這些變數;後半部的程式碼則負責處理物件的屬性和方法,包括設定兩個資料欄的Size屬性,以及用Append方法連結不同的物件。
圖23-6 按下「建立資料庫」按鈕以完成資料庫的建立 |
儘管新的資料庫中無任何資料錄,但資料庫已經有了完整的結構,隨時可以啟用;資料庫Phones中有一個資料表Phones,表中有兩個資料欄,Name和Number,它們的最大長度是30個字元。
存取資料庫
現在我們要設計一個簡單的程式,利用資料存取物件(同樣地,我們不用資料控制項)來存取Phones資料庫。這個程式讓你可以在資料表中前後移動,加入新的資料錄,並輸入任何文字以修改資料錄。你可以自己加上刪除及搜尋等功能。
請建立一個標準執行檔專案,在Form1中加入兩個指令按鈕,取名為cmdPrevious和cmdNext,把它們的Caption屬性分別設定為"Previous"和"Next";再加入兩個文字方塊控制項,取名為txtName和txtNumber。圖23-7是表單執行時的情形。
圖23-7 執行中的電話號碼資料庫程式 |
請將以下這段程式加入到表單中,然後執行這個應用程式。再次提醒你確定引用了DAO程式庫。
Option Explicit `Create new data access object variables Private dbWorkspace As Workspace Private dbDatabase As Database Private dbTable As Recordset Private dbName As Field Private dbNumber As Field Private Sub cmdNext_Click() `Move only if current record isn't a blank one If txtName.Text <> " " And txtNumber.Text <> " " Then `Save any changes to current record UpdateRecord `Move to next record dbTable.MoveNext `Prepare new record if at end of table If dbTable.EOF Then NewRecord `Display data from record DisplayFields End If `Keep focus on text boxes txtName.SetFocus End Sub Private Sub cmdPrevious_Click() `Save any changes to current record UpdateRecord `Step back one record dbTable.MovePrevious `Don't go past first record If dbTable.BOF Then dbTable.MoveNext `Display data from record DisplayFields `Keep focus on text boxes txtName.SetFocus End Sub Private Sub Form_Load() `Create data access objects Set dbWorkspace = DBEngine.Workspaces(0) `Change database path if necessary Set dbDatabase = dbWorkspace.OpenDatabase("C:\PHONES.MDB") Set dbTable = dbDatabase.OpenRecordset("Phones", dbOpenTable) `Use special handling if new database If dbTable.BOF And dbTable.EOF Then NewRecord `Start on first record dbTable.MoveFirst `Display data from record DisplayFields End Sub Private Sub NewRecord() `Add new record dbTable.AddNew `Install a space in each field dbTable!Name = " " dbTable!Number = " " `Update database dbTable.Update `Move to new record dbTable.MoveLast End Sub Private Sub UpdateRecord() `Prepare table for editing dbTable.Edit `Copy text box contents into record fields dbTable!Name = txtName.Text dbTable!Number = txtNumber.Text `Update database dbTable.Update End Sub Private Sub DisplayFields() `Display fields in text boxes txtName.Text = dbTable!Name txtNumber.Text = dbTable!Number End Sub
當使用者按下Previous或Next按鈕時,程式會更新目前的資料錄。由於我們並未使用任何資料連結控制項,表單上文字方塊控制項與資料庫中資料欄的連結工作完全要靠我們所寫的程式來完成,這比使用資料控制項要花較多的程式設計時間和精力,然而使用DAO卻使程式更具彈性。
舉個例子來說,原本我們的程式在移動到下一筆或上一筆資料錄時會進行資料的更新,我們可以很容易地改變這樣的設計──加入一個"Update"指令按鈕來執行更新的動作,或者是在文字方塊內的資料改變時進行更新的動作,這些不同的設計都可以輕易達成。所以,DAO使程式設計師掌握更大的彈性,更能設計出符合不同需求的程式。
如何產生報表?
在Visual Basic 6推出之前,設計和產生報表的工具幾乎都必須靠協力廠商的報表套裝軟體,不過,現在Visual Basic 6已經提供了這項功能。在Visual Basic環境中建立一個新專案時,你可以選擇「Data Environment專案」,這個專案裡有三種基本物件:DataEnvironment物件(提供資料庫連結、查詢和其他資料庫界面元素),DataReport物件(提供一個互動式的報表格式編輯界面)以及一個標準的表單。
DataReport物件會顯示表頭、表尾以及內容等三大部分。在這三大部分裡,你可以放入六種特別的控制項。這些控制項很類似標準的Label、TextBox、Image、Shape和Line控制項,但它們只能用在DataReport收納器中。另一個未提到的Function控制項則完全不同於任何標準控制項,它提供的是加總和其他計算的功能。