【テクニカル・上級編】DAO.Recordsetの「Type」プロパティを用いた、汎用的なデータインポート・エクスポート処理 – Access VBA解析バイブル

スポンサーリンク

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を混在させた際のトランザクション制御と、その競合回避について触れるとしよう。深淵はまだ続いている。

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