Accessの神髄:DAOメタデータ・リバースエンジニアリングによる「完全復元」のアーキテクチャ
Access開発者が避けて通れない「テーブル構造の変更」という悪夢。運用中にフィールドが増え、リレーションが組み替わり、インデックスが最適化される。この動的な構造変化に、我々はどのように立ち向かうべきか。
単なるデータ移行ではない。DAO(Data Access Objects)を掌握し、テーブルという「実体」を「メタデータ」へ昇華させ、再び実体へと再構成する。 この高度な抽象化こそが、レガシーを克服する唯一の道だ。
今日は、Accessの内部構造(TableDef, Field, Index, Relation)を完全に制御し、プログラムコードからテーブルを自己複製・復元するための極限の技術論を語る。
—
1. なぜ「DAO」でなければならないのか
ADOは確かに強力だが、Accessのローカルエンジン(ACE/JET)のメタデータ制御においては、DAOこそが神である。`.TableDefs`, `.Fields`, `.Indexes`, `.Relations` というDAOのコレクションは、Accessのカタログそのものだ。
これを操作する際、多くの初学者が陥る罠が「暗黙的な参照」と「メモリリーク」である。我々が書くべきコードは、ガベージコレクションに頼らず、自らの手でオブジェクトのライフサイクルを制御する「防弾仕様」でなければならない。
—
2. アーキテクチャの核心:メタデータ保存の戦略
テーブル構造をバックアップする際、単にデータをコピーするのではない。以下の階層をシリアライズ(テーブル化)する必要がある。
1. TableDef: テーブル名、属性(IsSystem, ValidationRule等)
2. Field: データ型、サイズ、Caption、DefaultValue、Required属性
3. Index: ユニーク制約、Primary Key、各フィールドの包含順序
4. Relation: 外部キー制約、更新・削除連鎖(Cascade Update/Delete)
—
3. 実装:TableDefの完全バックアップ・復元エンジン
以下は、あるテーブルの構造情報を別の「管理テーブル」へと書き出し、復元するクラス設計の概念である。
‘ —————————————————————————
‘ 極限のテーブル構造管理クラス: TableArchitect
‘ —————————————————————————
Option Explicit
Public Sub BackupTableStructure(ByVal targetTableName As String)
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim fld As DAO.Field
Dim idx As DAO.Index
Set db = CurrentDb
Set td = db.TableDefs(targetTableName)
‘ ここでメタデータ保存用テーブルへINSERT処理を行う
‘ Point: Field型(Typeプロパティ)はLong値なので、必ず数値で保存すること
‘ クリーンアップ:オブジェクトの明示的解放はVBAにおける礼儀である
Set td = Nothing
Set db = Nothing
End Sub
Public Sub RestoreTableStructure(ByVal metadataTableName As String)
Dim db As DAO.Database
Dim td As DAO.TableDef
Dim fld As DAO.Field
Set db = CurrentDb
‘ 1. テーブルの新規生成
Set td = db.CreateTableDef(“New_Table_Name”)
‘ 2. フィールドの動的構築
‘ CreateFieldメソッドの第3引数(Type)が重要。誤るとデータ整合性が崩壊する
Set fld = td.CreateField(“ID”, dbLong)
fld.Attributes = dbAutoIncrField ‘ 自動採番属性の付与
td.Fields.Append fld
‘ 3. テーブルの確定(反映)
db.TableDefs.Append td
‘ 4. インデックスとリレーションの再構築
‘ (略:Indexオブジェクトを生成し、td.Indexes.Appendする)
Set td = Nothing
Set db = Nothing
End Sub
—
4. シニアエンジニアが守るべき3つの鉄則
① リレーションの「削除順序」を厳守せよ
テーブルを再構築する際、リレーションが存在したままTableDefを削除しようとすると、Accessエンジンは「参照整合性違反」で拒絶する。`db.Relations.Delete` を行い、すべての制約を解除してから構造を破壊する。この順序制御が甘いシステムは、必ずどこかで「ゴミ」を残す。
② メモリの断片化を防ぐ(明示的な解放)
VBAの `Set = Nothing` は単なるおまじないではない。特にループ内で `TableDef` オブジェクトを生成・破棄する場合、明示的にNothingを代入しなければ、COMインターフェースが解放されず、メモリ肥大化を引き起こす。大規模なDB移行処理では致命的となる。
③ Windows APIによる進捗可視化
数万件のメタデータや大規模テーブルを扱う場合、Accessのフリーズはユーザーの不安を煽る。`User32.dll` の `GetTickCount` や、プログレスバーを自作して非同期的な感覚を与えることで、システムの「信頼性」を担保するのだ。
—
5. 結び:エンジニアの誇りとして
「Accessは簡易的なDBだから」と揶揄する輩がいる。しかし、その内部構造を理解し、メタデータまで自在に操る者にとっては、Accessは極めて強力なRAD(Rapid Application Development)ツールへと変貌する。
今回紹介した技術は、単なるツールの開発ではない。「システムの可変性」を担保するための設計哲学そのものである。
次に貴方がテーブル定義に手を入れる時、ただGUIの画面を操作するのではなく、裏側でDAOがどう動き、カタログ情報がどう書き換わっているのかを想像してほしい。それこそが、伝説となるための第一歩である。
—
追伸:もしリレーションの整合性で深い沼にはまったら、`db.Execute “ALTER TABLE…”` によるDDL直接発行とDAOの併用を検討せよ。それが最終的な「解」になる場合が多々ある。
