【実務・中級編】DAOとADOの使い分け:ローカルテーブル操作と外部DB連携の最適解 – Access VBA解析バイブル

スポンサーリンク

Access VBAを掌握せよ:DAOとADOの境界線で「事故らない」ためのアーキテクチャ論

Access開発において、DAO(Data Access Objects)とADO(ActiveX Data Objects)のどちらを使うべきか。この問いに対し、「ローカルはDAO、外部はADO」という教科書通りの回答だけで満足しているなら、あなたのシステムは潜在的なパフォーマンスの爆弾を抱えていると言わざるを得ません。

真のアーキテクトは、単に「何を使うか」ではなく、「データベースエンジンのライフサイクルと、メモリ消費の性質」を見極めて設計を選択します。今回は、実務の現場でバグをゼロに近づけ、保守性を極限まで高めるための技術的知見を授けます。

—

1. なぜDAOとADOの適材適所が「絶対的な正義」なのか

DAOはAccessデータベースエンジン(ACE/Jet)にネイティブ最適化されています。一方、ADOはOLE DBプロバイダを介した汎用的なデータアクセス層です。

  • DAOの強み: Access内部テーブルに対しては、物理的なデータ構造を直接操作できるため、オーバーヘッドが最小です。`Recordset`の更新効率はADOを圧倒します。
  • ADOの強み: SQL Server等の外部RDBMSと通信する際、非同期処理やストアドプロシージャの呼び出し、クライアントサイドカーソルによる柔軟なデータ制御が可能です。

結論: Access内部テーブルにADOで接続する、あるいは外部接続をDAOで行うのは、高級スポーツカーで砂利道を走るようなものです。

—

2. 現場で「事故る」原因は、接続の使い回しにある

多くの初心者が犯す最大の過ちは、DAOとADOのインスタンスをプロシージャ単位でバラバラに生成・破棄することです。これにより、メモリリークや接続ロックの競合が発生します。

堅牢な設計指針:接続の抽象化

DAOの場合は`CurrentDb`を、ADOの場合はグローバルな`ADODB.Connection`オブジェクトを適切に管理してください。

—

3. プロダクションコード:保守性と堅牢性を両立させる例

以下は、実務でそのまま利用できる、エラーハンドリングを完備したテンプレートです。

DAOによるローカル操作(高速・軽量)

Public Sub UpdateLocalTable()
‘ DAOはCurrentDb経由でアクセスするのが最も安全
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb
‘ dbOpenTableを使うことで、インデックスを最大限に活用可能
Set rs = db.OpenRecordset(“T_Master”, dbOpenTable)

On Error GoTo ErrorHandler
db.BeginTrans ‘ トランザクションでデータの整合性を担保

With rs
.Index = “PrimaryKey”
.Seek “=”, “TargetID”
If Not .NoMatch Then
.Edit
!Status = “Processed”
.Update
End If
End With

db.CommitTrans

CleanExit:
If Not rs Is Nothing Then rs.Close: Set rs = Nothing
Set db = Nothing
Exit Sub

ErrorHandler:
db.Rollback
MsgBox “エラー発生: ” & Err.Description
Resume CleanExit
End Sub

ADOによる外部SQL Server接続(堅牢・スケーラブル)

Public Sub ExecuteSQLServerCommand()
Dim conn As ADODB.Connection
Dim cmd As ADODB.Command

Set conn = New ADODB.Connection
‘ 接続文字列は環境変数や設定テーブルから読み込むこと
conn.ConnectionString = “Provider=SQLOLEDB;Data Source=ServerName;Initial Catalog=DBName;Integrated Security=SSPI;”
conn.Open

Set cmd = New ADODB.Command
Set cmd.ActiveConnection = conn

‘ ストアドプロシージャ実行を推奨(SQLインジェクション対策)
cmd.CommandText = “sp_UpdateCustomerStatus”
cmd.CommandType = adCmdStoredProc
cmd.Parameters.Append cmd.CreateParameter(“@ID”, adInteger, adParamInput, , 100)

cmd.Execute

conn.Close
Set cmd = Nothing
Set conn = Nothing
End Sub

—

4. アーキテクトからの助言:パフォーマンスを極めるために

1. トランザクションの範囲を最小化せよ:
トランザクション内での処理が長いと、他のプロセスをブロックし、デッドロックの原因となります。`BeginTrans`と`CommitTrans`の間に、ユーザー入力を待つような処理は絶対に記述してはいけません。
2. Recordsetのカーソルタイプを理解せよ:
ADOで外部DBに接続する際、`adOpenStatic`や`adLockReadOnly`を適切に使い分けるだけで、ネットワーク負荷は劇的に下がります。単にデータを表示するだけなら、サーバーサイドカーソルに拘る必要はありません。
3. クリーンアップの徹底:
VBAのオブジェクトは、スコープを抜けてもメモリを即座に解放するとは限りません。`Set obj = Nothing`を明示的に行い、異常終了時にも確実に実行される設計(上記コードの`CleanExit`)を標準化してください。

まとめ

DAOとADOの使い分けは、単なる好みの問題ではありません。「Accessというプラットフォームをどう制するか」という設計思想そのものです。

まずは、既存のコードを見直してください。もし`CurrentDb`を頻繁に`Set`していたり、不必要なADO接続をローカルテーブルに対して行っているなら、そこが改善の余地です。これらを徹底するだけで、あなたの開発するツールは、泥臭いスクリプトから、堅牢な業務アプリケーションへと進化します。

次回の記事では、これらの接続層をより抽象化した「データアクセスレイヤーの構築」について深掘りします。期待していてください。

タイトルとURLをコピーしました