DAOからADOへの移行チェックリスト:既存システムの保守性を損なわない「設計の転換」
こんにちは。今日もコードと向き合っているあなた、素晴らしいですね。
Access VBAを使いこなせるようになると、必ずと言っていいほど直面する「壁」があります。それは、「Access内部のデータ(ローカル)を扱う力はついたけれど、外部のサーバー(SQL Serverなど)へ手を伸ばしたい」という欲求です。
このとき、多くの人が足を踏み入れるのが「DAOからADOへの移行」という領域です。
「マクロの記録」から一歩踏み出し、本格的なプログラミングの世界へ足を踏み入れたあなたへ。今回は、単なる書き換え手順ではなく、システムの心臓部である「データの扱い方(アーキテクチャ)」をどう変えていくべきか、その極意を伝授します。
ここをクリアすれば、あなたは「Accessを使える人」から「データベースエンジニア」へと進化できるはずですよ。
1. なぜ「DAO」から「ADO」に変える必要があるのか?
まず、なぜわざわざ面倒な移行作業を行うのか、その理由を整理しましょう。ここを理解していないと、移行後に「なぜか動かない」「遅くなった」というトラブルに泣かされることになります。
DAO(Data Access Objects)とは?
DAOは、Access(Jet/ACEエンジン)の「内側に住んでいる住人」です。
Access内のテーブルを操作するなら、これほど速くて便利なものはありません。Access専用に設計されているため、非常に軽量で、Accessの機能をフルに活用できます。
ADO(ActiveX Data Objects)とは?
対してADOは、「世界中を旅する外交官」です。
OLE DBという共通の言葉を使うことで、Accessだけでなく、SQL Server、Oracle、あるいはWeb上のデータベースなど、あらゆる種類のデータベースと通信できます。
【結論】
- Access内のデータだけで完結するなら、DAOのままでOK。
- データをSQL Serverなどの外部サーバーへ移したい、あるいは将来的に移す可能性があるなら、ADOへの移行が必要。
2. アーキテクチャの違いを理解する(概念図)
コードを書く前に、頭の中に「データの通り道」を描いてください。
- DAOのルート:
`あなたのコード` $\rightarrow$ `Accessエンジン(ACE)` $\rightarrow$ `ローカルテーブル`
(直通ルートなので、非常に速い!)
- ADOのルート:
`あなたのコード` $\rightarrow$ `ADOライブラリ` $\rightarrow$ `OLE DBプロバイダ` $\rightarrow$ `ネットワーク` $\rightarrow$ `外部DB`
(通訳が必要なルートなので、設定が重要!)
この「通訳(プロバイダ)」が必要になることが、ADOを扱う際の最大のポイントです。
3. 移行のための「4つの重要チェックリスト」
既存のDAOコードをいきなり書き換えるのは、走行中の車のエンジンを交換するようなものです。以下のチェックリストに沿って、段階的に進めましょう。
① 接続管理(Connection)の分離
DAOでは `CurrentDb` を使えば、魔法のようにすぐに接続できました。しかし、ADOでは「接続文字列(ConnectionString)」という、住所や鍵を記した詳細な指示書が必要です。
- DAO: `Set db = CurrentDb` (自動で接続)
- ADO: `Set conn = New ADODB.Connection` $\rightarrow$ `conn.Open “接続文字列”` (手動で接続)
② カーソルタイプとロックタイプの選択
ここが一番の落とし穴です。ADOでは「データの見え方(カーソル)」と「データの守り方(ロック)」を明示的に指定する必要があります。
- CursorType: データをどう読み込むか(前方のみか、自由に行ったり来たりできるか)。
- LockType: 書き込むときにどうロックするか(読み取り専用か、更新可能か)。
③ トランザクションの範囲
「一連の処理がすべて成功するか、すべて失敗するか」を制御するトランザクション。DAOとADOでは、その「主導権を持つオブジェクト」が違います。
- DAO: `Database` オブジェクトが管理。
- ADO: `Connection` オブジェクトが管理。
④ レコードセットの「型」の変更
`DAO.Recordset` を `ADODB.Recordset` に変えるだけでは不十分です。ADO特有のプロパティ(`EOF` や `BOF` は共通ですが、エラーハンドリングの作法が微妙に異なります)に注意しましょう。
4. 実践:コードの書き換え例
では、実際に「テーブルからデータを読み取って表示する」という簡単な処理を比較してみましょう。
【Before】DAOによる実装(レガシーな書き方)
Access内のテーブルを直接触る、非常にシンプルな形です。
' --- DAOによる実装 ---
Sub Sample_DAO()
Dim db As DAO.Database
Dim rs As DAO.Recordset
' CurrentDbで現在のデータベースを直接取得
Set db = CurrentDb
' レコードセットを開く(非常にシンプル)
Set rs = db.OpenRecordset("SELECT EmployeeName FROM T_Employees", dbOpenSnapshot)
' データの読み取り
Do Until rs.EOF
Debug.Print rs!EmployeeName
rs.MoveNext
Loop
' 後片付け(これ、忘れがちなので注意!)
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
【After】ADOによる実装(モダンな書き方)
外部サーバーへの接続も意識した、堅牢な書き方です。
' --- ADOによる実装 ---
' ※参照設定で "Microsoft ActiveX Data Objects x.x Library" にチェックが必要です
Sub Sample_ADO()
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strConn As String
' 1. 接続文字列の定義(ここがADOの肝!)
' 今回はAccessファイル自体に接続する例ですが、
' ここを書き換えるだけでSQL Server等へ切り替えられます。
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & CurrentProject.FullName & ";"
' 2. オブジェクトの生成
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
On Error GoTo ErrorHandler
' 3. 接続の確立
conn.Open strConn
' 4. レコードセットを開く
' CursorType: adOpenStatic (静的カーソル:データの移動が自由)
' LockType: adLockReadOnly (読み取り専用:パフォーマンス重視)
rs.Open "SELECT EmployeeName FROM T_Employees", conn, adOpenStatic, adLockReadOnly
' 5. データの読み取り
Do Until rs.EOF
Debug.Print rs!EmployeeName
rs.MoveNext
Loop
' 6. 後片付け
rs.Close
conn.Close
CleanUp:
Set rs = Nothing
Set conn = Nothing
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
5. 伝説のエンジニアからのアドバイス
最後に、移行を成功させるための「魂の助言」を贈ります。
「一気に全部変えようとしないこと」
システムが大規模なら、全てのDAOコードを一度にADOにする必要はありません。
新しい機能や、外部サーバーと連携する部分だけを「ADOモジュール」として切り出し、既存のDAOコードとは共存させる。これが、保守性を保ちながらシステムを近代化する、プロの戦い方です。
また、「エラーハンドリング」を絶対に疎かにしないでください。
ネットワーク越しにデータをやり取りするADOは、DAOよりも「通信断」などのトラブルが起こり得ます。`On Error GoTo` を使い、接続が切れたときに安全に後片付け(`Close`)ができる構造を必ず作ってください。
一歩ずつ、着実に。
この壁を乗り越えたとき、あなたの作るアプリケーションは、ローカルの小さな道具から、世界中のデータとつながる強力な武器へと進化します。
応援していますよ。頑張ってくださいね!
