DAO

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 AccessMicrosoft ExceldBase等等檔案型資料來源都可以利用Microsoft Jet資料庫引擎就可以使用SQL指令目前的Jet引擎最新版本為4.0,並且未來在x64平台上將不再支援。
    使用Jet 連到Access.Text.Excel


DAO物件模型 For Microsoft Jet Workspaces:Access說明→內容→DAO 3.60

宣告(定義)物件變數

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 )
記錄集的型態
語法型態說明
dbOpenTableTable-typeMS Jet Workspaces only 
dbOpenDynasetDynaset-typelinked table or query 預設值 
dbOpenSnapshotSnapshot-type
dbOpenForwardOnlyForward-only-typeODBCDirect Workspaces 預設值 
dbOpenDynamicDynamic-typeODBCDirect Workspaces only 
比較表:
RecordsetMembershipRecords Updatableresult of a query 
Table-typeCan changeCan add, change, delete N/A
Dynaset-typeFixedCan add, change, delete Yes
Snapshot-typeFixedFixedYes
Forward-only-typeFixedFixedYes
Dynamic-typeCan changeCan add, change, delete Yes
存取記錄集的資料
針對目前指標所在的當筆記錄。例如:存取記錄集中目前記錄的 " 姓名 " 欄位資料,以第三種方法最快。
  1. [LName] = rs.Fields("姓名").Value
  2. [LName] = rs("姓名")
  3. [LName] = rs![姓名]

移動記錄集指標

用以改變記錄集物件,目前所在記錄指標的位置。有 " 方法 " 和 " 屬性 " 兩種設定方式。
方法:
  • MoveFirst:第一筆
  • MoveLast:最後一筆
  • MoveNext:下一筆
  • MovePrevious:上一筆
  • Move rows [,start] :移動若干筆,從第幾筆開始
屬性:
  • BOF:Begin Of Flie 
  • EOF:End Of File 
  • RecordCount:記錄筆數
  • PercentPosition:位置百分比
注意:
  1. 若目前記錄指標 ( Current Row ) 已經在第一筆,BOF 屬性為 True,再使用 MovePrevious ,則BOF 屬性仍為 True,但會出現執行時期錯誤 ( run-time error )。
  2. 若目前記錄指標 ( Current Row ) 已經在最後一筆,EOF 屬性為 True,再使用 MoveNext ,則 EOF 屬性仍為 True,但會出現執行時期錯誤 ( run-time error )。

資料處理

更新記錄
  1. Edit method →Modify data →Update method 
  2. Run-time erroe if Update without Edit or AddNew
例如:
rs.Edit
rs("Last Name")=[LName]
rs.Update
新增記錄
  1. AddNew method →Add data →Update method
  2. Changes lost if no Update is executed
例如:
rsCustomers.AddNew
rsCustomers("Customer ID")="FINNF"
rsCustomers("Company Name")="Finnegan's Foods"
rsCustomers.Update
刪除記錄
Delete Method
  1. Removes current record
  2. No warning or prompt occurs
  3. 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 comparisonkey1, 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

使用查詢物件

使用選取查詢
  1. Set QueryDef Object to Query ( 定義查詢定義物件 ) 
    • Dim qdf As QueryDef
    • Set qdf=db.QueryDefs("Products On Order")
  2. Set any Parameters ( 設定參數 ) 
    • qdf.Parameters("Beginning Date")=#01/01/94#
  3. 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
  1. SQL Select Statement
    • strSQL = " Selcet * From Employees "
    • Set rs = db.OpenRecordset ( strSQL, dbOpenDynaset )
  2. SQL Update Statement - Useful for batch updates 
    • strSQL = " Update Products Set [ Discount ] = 1 Where [ Discount ] = 0 " 
    • db.Execute strSQL, dbFailOnError
  3. SQL Insert Statememt - May be faster than AddNew
    • strSQL = " Insert Into Employees... "
    • db.Execute strSQL, dbFailOnError

Transactions ( 交易 )

一筆更新,將在兩個資料表產生對應的變動,而且必須同時完成。
  1. Transaction Methods of Workspace Object 
    • BeginTrans - begins a transaction
    • CommitTrans - commits all changes
    • Rollback - cancels all changes since BeginTrans 
  2. Transactions Can Improve Performance 

Lock ( 鎖定 )

以 Access 資料庫的查詢為例:
  1. 建立查詢→修改查詢中的某一筆記錄,並保持編輯狀態,
  2. 再開啟 MS Access →開啟同一個資料庫檔案。( 若以開啟舊檔方式開啟同一個資料庫,將無法產生二個資料庫視窗。)
  3. 開啟同一個查詢物件→修改同一筆記錄,
  4. 先後儲存查詢→測試記錄鎖定狀態,是否允許更新或修改。
查詢設計檢視→屬性→記錄鎖定:
  • 無鎖定:預設值。允許多使用者同時編輯,但儲存時進行鎖定。
  • 所有記錄:只允許一個使用者編輯同一個查詢。
  • 編輯的記錄:允許多使用者同時開啟同一個查詢,但不允許同時編輯同一筆記錄。
記錄鎖定屬性設定:
  • 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