先達はあらまほしきことなり

デジタルテクノロジーの活用と展望

DAOとADO

VBAプログラマーならどちらを使うかで頭を使った経験があるはず。
私の経験では、DAOの方が便利な場合が多いかなという印象。

歴史的には、DAOがまず開発されて、その後にADOが登場した。
そのため、ADOの方がパフォーマンスが高いという風潮が一部にあるが、パフォーマンスの違いは、気にならない程度の差で、どちらの処理が速いかはケースバイケースだ。
体感的に差を感じることはまずないといってよい。

ADOはODBC接続なしに外部データベースに接続することも可能なのだが、多くの場合ODBC接続なしでのデータベース操作は現実的でない。
なぜなら、リンクテーブルやパススルークエリを使うにはODBC接続が必須だからだ。
したがって、ODBC接続しないで済むから(=ODBCドライバーをインストールする必要がない)からADOという選択にはならない。

パススルークエリを作成するコード例を紹介する。
以下のコードでは次の2つの点でDAOの方が優れている。

  1. DAOの方が、ADOより簡潔に記述できる
  2. DAOは名前なしクエリを実行できる


■DAOで名前なしクエリを実行(INSERT UPDATE DELETE)
Public Sub execPssThrQ(dsnName As String, database As String, user As String, pwd As String, SQL As String)
On Error GoTo Err_Handle    
    
    Dim WS As DAO.Workspace
    Dim DB As DAO.Database
    Dim QD As DAO.QueryDef
    
    Set WS = DBEngine.Workspaces(0)
    Set DB = CurrentDb
    Set QD = DB.CreateQueryDef("")
    
    QD.Connect = "ODBC;DSN=" & dsnName & ";DATABASE=" & database & ";UID=" & user & ";PWD=" & pwd
    QD.ReturnsRecords = False
    QD.SQL = SQL
    WS.BeginTrans               'トランザクション開始
    QD.Execute
    WS.CommitTrans              'コミット
    
exit_prc:

    Set WS = Nothing
    Set DB = Nothing
    Set QD = Nothing
    Exit Sub
    
Err_Handle:
    
    WS.Rollback                 'ロールバック
    GoTo exit_prc

End Sub


■DAOで名前なしクエリでレコードセットを取得(SELECT)
Public Function getRSbyPssThrQ(dsnName As String, database As String, user As String, pwd As String, SQL As String) As DAO.Recordset

    Dim QD As DAO.QueryDef
    Set QD = CurrentDb.CreateQueryDef("")
    QD.Connect = "ODBC;DSN=" & dsnName & ";DATABASE=" & database & ";UID=" & user & ";PWD=" & pwd
    QD.ReturnsRecords = True
    QD.SQL = SQL
    Set getRSbyPssThrQ = QD.OpenRecordset()
    Set QD = Nothing

End Function


■ADOで名前ありクエリを作成(SELECT)
Public Sub createNamedPssThrQ(dsnName As String, database As String ,user As String pwd As String, SQL As String, queryName As String)
    
    Dim cat As ADOX.Catalog
    Dim cmd As ADODB.Command
    
    Set cat = New ADOX.Catalog
    Set cmd = New ADODB.Command
    
    cat.ActiveConnection = CurrentProject.Connection
    Set cmd.ActiveConnection = cat.ActiveConnection
    cmd.CommandText = SQL
    cmd.Properties("Jet OLEDB:ODBC Pass-Through Statement") = True
    cmd.Properties _
     ("Jet OLEDB:Pass Through Query Connect String") = _
       "ODBC;DSN=" & dsnName & ";database=" & database & ";UID=" & user & ";PWD=" & pwd & ";"
    
    '存在する場合はいったん削除する
    Dim obj As AccessObject
    For Each obj In CurrentData.AllQueries
        If obj.Name = queryName Then
            DoCmd.DeleteObject acQuery, queryName
            Exit For
        End If
    Next

    'クエリオブジェクトを追加する
    cat.Procedures.Append queryName, cmd

    Set cat = Nothing
    Set cmd = Nothing

End Sub


本記事ではDAOの良い点を紹介したが、私はDAO派というわけではない。
私はDAOとADOを併用している。

ADOで私が重宝しているプロパティがいくつかある。
例えば、AbsolutePage プロパティだ。
(プロパティの内容は割愛)
このようなプロパティはDAOにはない。

どっち派が有利かの観点は生産的ではなく、両刀づかいになった方がよい。