DAO物件(Data Access Object)
資料來源 : http://jsl0924.myweb.hinet.net/access/aca4.htm
我們在Access 的表單劃面中,可以使用DAO或ADO物件,來存取其他的資料庫(excel)中的資料。
DAO說明前先了解Jet 是什麼:
- Access採用 Microsoft Jet 資料庫引擎.
- Microsoft Jet 資料庫引擎可以存取如 Access、FoxPro、dBase等關聯式資料庫。
- 所有的DAO查詢服務必須在本機上執行,遠端的資料需先傳送到本機才可處理。
- Microsoft Jet是微軟針對檔案型資料庫所發展的資料庫引擎(Database Engine),它的適用資料來源種類相當多,像是Microsoft Access、Microsoft Excel、dBase等等檔案型資料來源都可以利用Microsoft Jet資料庫引擎就可以使用SQL指令,目前的Jet引擎最新版本為4.0,並且未來在x64平台上將不再支援。

使用Jet 連到Access.Text.Excel
宣告(定義)物件變數
Dim ObjVar As MyClass:宣告一個物件變數,類別為 MyClass,此時物件尚未存在。
Set ObjVar = [ New ] MyClass :以 New ( 可省略 ) 產生一個物件,並用 Set 把他指派給 ObjVar 變數。
開啟資料庫(OpenDatabase)
Set 參數一 = 參數二.OpenDatabase (參數三, 參數四, 參數五, 參數六)
- 參數一:database 資料庫物件變數。
- 參數二:workspace 工作區名稱。預設是Workspaces ( 0 ),可省略。
- 參數三:dbname 資料庫名稱,包含完整路徑。
- 參數四:options True表示 " 獨佔 " ;False表示 " 共享 "。
- 參數五:read-only True表示 " 唯讀 ";False表示 " 非唯讀 "。
- 參數六:connect 連結資訊、密碼。
例如:
Dim db As Database
Set db = OpenDatabase ( " mydb.mdb ", False, False )
指派資料庫物件為目前資料庫的三個方法
- Set db = DBEngine.Workspaces( 0 ). DataBases( 0 )
- Set db = DBEngine( 0 )( 0 )
- Set db = CurrentDB( ) ( 使用 CurrentDb 函數 )
- db.Close '使用 Close 方法,關閉資料庫
建立記錄集(OpenRecordset)
For Database objects:
Set recordset = object.OpenRecordset (source, type, options, lockedits)
For QueryDef, Recordset, and TableDef objects:
Set recordset = object.OpenRecordset (type, options, lockedits)
- recordset :記錄集物件變數。
- object :想要建立記錄集的物件,如 Database, QueryDef, Recordset, and TableDef objects。
- source :可以是資料表、查詢或者SQL陳述式。
- type :記錄集型態。如 dbOpenTable ... 等,若在 MS Jet Workspace 建立記錄集,可以不指定型態,預設為 dbOpenTable ( 開啟資料表型態記錄集 )。
- options :如 dbAppendOnly, dbDenyWrite, dbDenyRead, dbReadOnly ... 等。
- lockedits :鎖定編輯。如 dbReadOnly, dbPessimistic, dbOptimistic ... 等
例如:
Dim rs As Recordset , sql As String
Set rs = db.OpenRecordset ( " 員工 " , dbOpenTable )
sql = " SELECT [姓名] FROM 員工 "
Set rs = db.OpenRecordset ( sql , dbOpenDynaset )
Set rs = db.OpenRecordset ( sql , dbOpenSnapshot )
記錄集的型態
| 語法 | 型態 | 說明 |
|---|---|---|
| dbOpenTable | Table-type | MS Jet Workspaces only |
| dbOpenDynaset | Dynaset-type | linked table or query 預設值 |
| dbOpenSnapshot | Snapshot-type | |
| dbOpenForwardOnly | Forward-only-type | ODBCDirect Workspaces 預設值 |
| dbOpenDynamic | Dynamic-type | ODBCDirect Workspaces only |
比較表:
| Recordset | Membership | Records Updatable | result of a query |
|---|---|---|---|
| Table-type | Can change | Can add, change, delete | N/A |
| Dynaset-type | Fixed | Can add, change, delete | Yes |
| Snapshot-type | Fixed | Fixed | Yes |
| Forward-only-type | Fixed | Fixed | Yes |
| Dynamic-type | Can change | Can add, change, delete | Yes |
存取記錄集的資料
針對目前指標所在的當筆記錄。例如:存取記錄集中目前記錄的 " 姓名 " 欄位資料,以第三種方法最快。
- [LName] = rs.Fields("姓名").Value
- [LName] = rs("姓名")
- [LName] = rs![姓名]
移動記錄集指標
用以改變記錄集物件,目前所在記錄指標的位置。有 " 方法 " 和 " 屬性 " 兩種設定方式。
方法:
- MoveFirst:第一筆
- MoveLast:最後一筆
- MoveNext:下一筆
- MovePrevious:上一筆
- Move rows [,start] :移動若干筆,從第幾筆開始
屬性:
- BOF:Begin Of Flie
- EOF:End Of File
- RecordCount:記錄筆數
- PercentPosition:位置百分比
注意:
- 若目前記錄指標 ( Current Row ) 已經在第一筆,BOF 屬性為 True,再使用 MovePrevious ,則BOF 屬性仍為 True,但會出現執行時期錯誤 ( run-time error )。
- 若目前記錄指標 ( Current Row ) 已經在最後一筆,EOF 屬性為 True,再使用 MoveNext ,則 EOF 屬性仍為 True,但會出現執行時期錯誤 ( run-time error )。
資料處理
更新記錄
- Edit method →Modify data →Update method
- Run-time erroe if Update without Edit or AddNew
例如:
rs.Edit
rs("Last Name")=[LName]
rs.Update
新增記錄
- AddNew method →Add data →Update method
- Changes lost if no Update is executed
例如:
rsCustomers.AddNew
rsCustomers("Customer ID")="FINNF"
rsCustomers("Company Name")="Finnegan's Foods"
rsCustomers.Update
刪除記錄
Delete Method
- Removes current record
- No warning or prompt occurs
- Your code should move off deleted record
例如:
rs.Delete
If rs.EOF Then
rs.MoveLast
End If
搜尋記錄
Find:
- For a Dynaset-type or Snapshot-type Recordset Only
- 一筆一筆地比對
- 使用屬性 " Bookmark " 儲存目前指標位置
- FindFirst, FindLast, FindNext, FindPrevious
語法:rs.FindFirst criteria ( criteria = any valid Where clause without Where. )
例如:
Public Sub DAO_Find()
...
strFind="[職稱]='業務經理'"
rs.FindFirst strFind
Do Until rs.NoMatch
Debug.Print rs("姓名")
rs.FindNext strFind
Loop
...
End Sub
注意:為了避免混淆,在雙引號中若需再加上雙引號,請使用單引號,加以區別。
Seek:
- For a Table-Type Recordset Only
- 只能搜尋定義過 " 索引 " 的欄位
- 採 " 二分法 " 比對
語法:rs.Seek comparison, key1, key2... ( comparison:比較運算子 )
例如:
Public Sub DAO_Seek()
Dim ...
...
rs.INDEX="PrimaryKey"
rs.Seek "=",7
If Not rs.NoMatch Then
Debug.Print rs("姓名")
End If
...
End Sub
使用查詢物件
使用選取查詢
- Set QueryDef Object to Query ( 定義查詢定義物件 )
- Dim qdf As QueryDef
- Set qdf=db.QueryDefs("Products On Order")
- Set any Parameters ( 設定參數 )
- qdf.Parameters("Beginning Date")=#01/01/94#
- Create Recordset ( 建立記錄集 )
- Set rs=qdf.OpenRecordSet(dbOpenDynaset)
使用動作查詢
Execute Method - Executes an action query
- No recordset created
- Use DB_FailOnError to return a run-time error if query fails
使用SQL
- SQL Select Statement
- strSQL = " Selcet * From Employees "
- Set rs = db.OpenRecordset ( strSQL, dbOpenDynaset )
- SQL Update Statement - Useful for batch updates
- strSQL = " Update Products Set [ Discount ] = 1 Where [ Discount ] = 0 "
- db.Execute strSQL, dbFailOnError
- SQL Insert Statememt - May be faster than AddNew
- strSQL = " Insert Into Employees... "
- db.Execute strSQL, dbFailOnError
Transactions ( 交易 )
一筆更新,將在兩個資料表產生對應的變動,而且必須同時完成。
- Transaction Methods of Workspace Object
- BeginTrans - begins a transaction
- CommitTrans - commits all changes
- Rollback - cancels all changes since BeginTrans
- Transactions Can Improve Performance
Lock ( 鎖定 )
以 Access 資料庫的查詢為例:
- 建立查詢→修改查詢中的某一筆記錄,並保持編輯狀態,
- 再開啟 MS Access →開啟同一個資料庫檔案。( 若以開啟舊檔方式開啟同一個資料庫,將無法產生二個資料庫視窗。)
- 開啟同一個查詢物件→修改同一筆記錄,
- 先後儲存查詢→測試記錄鎖定狀態,是否允許更新或修改。
查詢設計檢視→屬性→記錄鎖定:
- 無鎖定:預設值。允許多使用者同時編輯,但儲存時進行鎖定。
- 所有記錄:只允許一個使用者編輯同一個查詢。
- 編輯的記錄:允許多使用者同時開啟同一個查詢,但不允許同時編輯同一筆記錄。
記錄鎖定屬性設定:
- rs.LockEdits = True ( Pessimistic, 悲觀的 ) - Default
Lock from Edit through Update
- rs.LockEdits = False ( Optimistic, 樂觀的 )
Lock during Update only
設計具載入資料命令鈕的表單(DAO實作)
修改同一個物件的多個屬性:
With 物件名稱
.物件屬性1 = 屬性1
.物件屬性2 = 屬性2
...
End With
將 Recordset 的指標,指定給表單的指標:
Me.Bookmark = rs.Bookmark
RecordsetClone:
參照表單屬性 Recordsource 指定的 Recordset 物件。
除了自行設計的表單之外,利用精靈建好表單,再建立按鈕→將程式碼由範例中複製過來→重新設定建立 Recordset 物件。
Private Sub Form_Load ()
Set res = Me.RecordsetClone
End Sub



