Access VBAの深淵:DAO.Recordsetと動的型判定による「無敗のデータ転送」
Access開発の現場において、`DoCmd.TransferDatabase` や単純なクエリによるテーブルコピーは、小さな案件では通用しても、大規模なシステム間連携やレガシーなデータ移行においては「子供の遊び」に過ぎない。
データ型が不整合を起こし、NULLの扱いで沈没し、予期せぬ実行時エラーで深夜のパッチ修正に追われる――そんな悲劇を回避するためには、`DAO.Recordset`のメタデータを掌握し、メモリを極限まで制御するプロフェッショナルなアプローチが必要だ。
今日は、フィールドのデータ型を動的に判定し、型変換エラーを完璧に封じ込める「汎用データ転送エンジン」の核心を伝授する。
—
1. 汎用性の罠と「型判定」の真実
DAOの`Field.Type`プロパティは、単なる整数値ではない。これはデータベースエンジンがデータをどう解釈すべきかを示す「設計図」そのものだ。
安易な`Value`のコピーは、Long型にNullが混入した瞬間に沈没する。我々が書くべきは、ソースとターゲットの型を対照させ、必要に応じて変換を噛ませるアーキテクチャだ。
DAO.DataTypeEnumの極意
`dbLong`, `dbText`, `dbMemo` など、DAOが提供する定数は多岐にわたる。これを汎用プロシージャで扱う際の肝は、「DAOのメタデータから自動的にマッピングを決定する」ことにある。
—
2. 実装:堅牢なデータ転送プロシージャ
以下は、私が長年使い回している「型安全な転送ロジック」の雛形だ。メモリリークを防ぐため、オブジェクトの明示的な解放と、エラーハンドリングの徹底を前提としている。
‘ 汎用データ転送プロシージャ
‘ ソースとターゲットのレコードセットを渡し、フィールド名が一致する限り転送を行う
Public Sub TransferDataRobust(ByRef rsSrc As DAO.Recordset, ByRef rsDst As DAO.Recordset)
Dim fldSrc As DAO.Field
Dim fldDst As DAO.Field
On Error GoTo Err_Handler
‘ トランザクションで囲むことで、万が一の失敗時にロールバックを確約する
DBEngine.BeginTrans
rsDst.AddNew
For Each fldSrc In rsSrc.Fields
‘ ターゲット側に同名のフィールドが存在するか確認
On Error Resume Next
Set fldDst = rsDst.Fields(fldSrc.Name)
If Err.Number = 0 Then
‘ Null判定を徹底する。これがデータ移行の生存率を左右する
If IsNull(fldSrc.Value) Then
fldDst.Value = Null
Else
‘ 型変換が必要な特殊ケース(必要に応じて分岐を拡張せよ)
‘ 例:DAO.dbMemoとDAO.dbTextの整合性など
fldDst.Value = fldSrc.Value
End If
End If
On Error GoTo Err_Handler
Next fldSrc
rsDst.Update
DBEngine.CommitTrans
Exit_Proc:
Set fldSrc = Nothing
Set fldDst = Nothing
Exit Sub
Err_Handler:
DBEngine.Rollback
Debug.Print “Error: ” & Err.Description & ” / Field: ” & fldSrc.Name
Resume Exit_Proc
End Sub
—
3. レガシー環境を生き抜くためのメモリ最適化
Access VBAにおいて、`Recordset`を漫然と開いたままにするのは「メモリの自爆」を意味する。
1. 暗黙的解放を信じるな: `Set rs = Nothing` はマナーではなく、生存戦略だ。特にループ内でRecordsetを生成する場合、明示的な解放を行わなければ、メモリの断片化が起き、いずれシステムはリソース不足でクラッシュする。
2. Windows APIによる監視: 大規模なバッチ処理を行う際は、`GlobalMemoryStatusEx` を利用して、システムメモリの空き容量を監視し、一定の閾値を超えたら強制的に `DBEngine.Idle dbRefreshCache` を呼び出し、メモリを解放する仕組みを組み込むのが、伝説的なアーキテクトの作法だ。
—
4. 結び:技術至上主義の現場へ
今回紹介したコードは、単なる「型コピー」ではない。データという資産を、異なる構造の間で安全に移送するための「防波堤」だ。
Accessは古いプラットフォームと言われるが、そのDAOの深淵に潜り込み、メモリの挙動を支配すれば、これほど柔軟かつ強力な開発環境は他にない。
諸君、既存のライブラリに頼るな。DAOのメタデータと、メモリというハードウェアの制約を理解した者が、真に「業務を自動化する」ことができるのだ。
次は、ADODBとDAOを混在させた際のトランザクション制御と、その競合回避について触れるとしよう。深淵はまだ続いている。
