こんにちは!データベース設計やAccessの裏側の仕組みに興味を持つあなたへ。
今日は、Access VBAの真骨頂とも言える、少しワクワクするような高度なテクニックのお話をしますね。
「マクロの記録」ボタンを押すだけの自動化から一歩抜け出して、プロの現場で使われている「メタデータ駆動型開発(Metadata-Driven Development)」の世界を覗いてみましょう。
ここをクリアすれば、Access VBAの基本はもちろん、システムアーキテクチャの本質がグッと見えてきますよ。しっかり伴走しますので、リラックスしてついてきてくださいね!
—
1. なぜ「JSON定義からのテーブル自動生成」なのか?
通常、Accessでテーブルを作るときは、デザインビューを開いてポチポチとフィールド名やデータ型を手動で設定しますよね。リレーションシップも画面上で線を引っ張って作ります。
しかし、システムが大きくなったり、バージョンアップが頻繁に行われたりすると、こんな悩みが出てきませんか?
- 「どのテーブルにどのフィールドがあるか、ドキュメントと実物が乖離してきた…」
- 「新しい環境にシステムを展開するたびに、手作業でテーブルを作るのはミスのもとだ」
- 「仕様変更のたびにコードを書き直すのはもう限界!」
ここで登場するのが「メタデータ駆動」という発想です。
「データについてのデータ(メタデータ)」、つまりテーブルの設計図をJSONというテキストファイルで外部に持ち、Accessの起動時にそれを読み込んで、テーブルやリレーションを勝手に構築・修復しちゃおうというアプローチです。
これぞ、プログラミングの醍醐味。「手作業の排除」と「完全な再現性」を手に入れるための最強の武器になります。
—
2. 全体像のイメージ:どうやって動くの?
仕組みは意外とシンプルです。以下の3ステップで動きます。
1. JSONの読み込み: あらかじめ用意された `schema.json`(テーブル名、フィールド名、データ型、リレーションの定義)をVBAで読み取ります。
2. TableDefによるテーブル構築: DAO(Data Access Objects)の `TableDef` オブジェクトを操作し、テーブルやフィールドをプログラムからゴリゴリ作ります。
3. Relationによるリレーション構築: 主キーと外部キーの結びつき(リレーションシップ)を動的にプログラムで定義します。
それでは、具体的なコードを見ていきましょう!
—
3. 実装コード:メタデータ駆動エンジン
今回は、VBAから扱いやすいように、JSONのパース(解析)処理と、AccessのDAO操作を組み合わせたサンプルコードを作成しました。
> ※ 事前準備として、VBAのVBE画面(Alt + F11)の「ツール」>「参照設定」から 「Microsoft DAO 3.6 Object Library」(またはACCDBの場合はそれに準ずるDAOライブラリ)にチェックを入れておいてくださいね。
① 設計図となるJSONファイルの例 (`schema.json`)
プロジェクトと同じフォルダに、以下のような `schema.json` を置いておきます。
{
“tables”: [
{
“name”: “M_Category”,
“fields”: [
{“name”: “CategoryID”, “type”: “Long”, “attributes”: “PrimaryKey”},
{“name”: “CategoryName”, “type”: “Text”, “size”: 50}
]
},
{
“name”: “T_Product”,
“fields”: [
{“name”: “ProductID”, “type”: “Long”, “attributes”: “PrimaryKey”},
{“name”: “ProductName”, “type”: “Text”, “size”: 100},
{“name”: “CategoryID”, “type”: “Long”}
],
“relations”: [
{
“foreignTable”: “T_Product”,
“foreignField”: “CategoryID”,
“primaryTable”: “M_Category”,
“primaryField”: “CategoryID”
}
]
}
]
}
② テーブルを自動構築するVBAモジュール
標準モジュールに以下のコードを貼り付けて実行してみてください。
Option Explicit
‘ ==============================================================================
‘ メイン処理:JSON定義からデータベースを構築する
‘ ==============================================================================
Public Sub BuildDatabaseFromJSON()
Dim jsonPath As String
jsonPath = CurrentProject.Path & “\schema.json”
‘ ファイルの存在確認
If Dir(jsonPath) = “” Then
MsgBox “スキーマ定義ファイルが見つかりません: ” & jsonPath, vbCritical
Exit Sub
End If
Dim jsonText As String
jsonText = ReadTextFile(jsonPath)
‘ 【簡易パーサーの代わりとしての注意】
‘ 本格的なJSONパースにはVBA用JSONパーサー(VBA-JSONなど)を推奨しますが、
‘ 今回は概念理解のため、DAOを使ったテーブル構築ロジックに集中します。
MsgBox “JSON定義の読み込みに成功しました。テーブル構築を開始します。”, vbInformation
‘ ※実務ではここでJSONを解析し、以下のプロシージャに渡します。
‘ 今回は解説用に、概念的なDAO操作の核心部分を見ていきましょう。
End Sub
‘ ==============================================================================
‘ DAOを使ったテーブル動的生成のコアロジック
‘ ==============================================================================
Public Sub CreateTableDemo()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim idx As DAO.Index
Set db = CurrentDb()
On Error GoTo ErrorHandler
‘ すでにテーブルが存在する場合は削除して作り直す(初期化の例)
‘ ※本番環境では既存データの保護ロジックが必要です
If TableExists(“T_Product”, db) Then
db.TableDefs.Delete “T_Product”
End If
‘ 1. TableDefオブジェクトの新規作成
Set tdf = db.CreateTableDef(“T_Product”)
‘ 2. フィールドの追加
‘ ProductID (長整数型 / 主キー)
Set fld = tdf.CreateField(“ProductID”, dbLong)
tdf.Fields.Append fld
‘ ProductName (テキスト型 / 100文字)
Set fld = tdf.CreateField(“ProductName”, dbText, 100)
tdf.Fields.Append fld
‘ CategoryID (長整数型)
Set fld = tdf.CreateField(“CategoryID”, dbLong)
tdf.Fields.Append fld
‘ 3. テーブルをデータベースに登録
db.TableDefs.Append tdf
‘ 4. 主キー(Primary Key)の設定はIndexオブジェクトを使用します
Set idx = tdf.CreateIndex(“PrimaryKey”)
idx.Fields.Append idx.CreateField(“ProductID”)
idx.Primary = True
idx.Unique = True
tdf.Indexes.Append idx
MsgBox “テーブル ‘T_Product’ の作成が完了しました!”, vbInformation
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub
‘ ==============================================================================
‘ 補助関数:テーブルの存在確認
‘ ==============================================================================
Private Function TableExists(tableName As String, db As DAO.Database) As Boolean
Dim tdf As DAO.TableDef
TableExists = False
For Each tdf In db.TableDefs
If tdf.Name = tableName Then
TableExists = True
Exit For
End If
Next tdf
End Function
‘ ==============================================================================
‘ 補助関数:テキストファイルの読み込み
‘ ==============================================================================
Private Function ReadTextFile(filePath As String) As String
Dim fso As Object
Dim ts As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Set ts = fso.OpenTextFile(filePath, 1, False, -1) ‘ 1=ForReading, -1=Unicode(UTF-8等対応)
ReadTextFile = ts.ReadAll
ts.Close
End Function
—
4. 陥りやすい罠とプロの回避術
このメタデータ駆動開発に挑戦するとき、多くのエンジニアがハマる「落とし穴」があります。ここを知っておくだけで、開発スピードが何倍も変わりますよ。
罠①:「リレーションシップの呪縛」
テーブルを作る順番を間違えると、リレーション(外部キー制約)を貼るときにエラーになります。
- 回避術: リレーションを貼る際は、「親テーブル」が完全に作成され、主キーが定義されている状態でなければなりません。必ず「すべてのテーブルを作るフェーズ」と「リレーションを貼るフェーズ」をプログラム内で完全に分離させましょう。
罠②:「開いているテーブルの削除エラー」
VBAで `db.TableDefs.Delete` を実行しようとしたとき、そのテーブルを画面(データシートビュー)で開いていると、容赦なく実行時エラーになります。
- 回避術: 処理の最初に、対象のテーブルやクエリがアクティブになっていないかチェックするか、エラーハンドリング(`On Error Resume Next` など)を適切に挟んで安全に落とす設計にしましょう。
—
まとめ:ここをクリアすれば、Access VBAの基本はバッチリ!
今回は、JSON定義ファイルからテーブル構造を自動構築する「メタデータ駆動型開発」の極意をお伝えしました。
- TableDef を使えば、Accessの画面を使わずにプログラムだけで自由自在にテーブル構造を操れること。
- 外部の設計図(JSONなど)とプログラムを分離することで、保守性が劇的に向上すること。
この2つを理解できたあなたは、もうただの「Accessのマクロを作る人」ではありません。立派なデータベース・アーキテクトへの道を歩んでいます。
最初は難しく感じるかもしれませんが、コードを動かしてテーブルが自動でパッと生成された瞬間の感動は格別です。ぜひご自身の開発環境でも試してみてくださいね。
それでは、また次の知見でお会いしましょう!バッチリ使いこなしてくださいね!
