【上級】巨大なフラットテーブルを解体せよ:Access VBAで実現する「自動正規化エンジン」の設計術
こんにちは。現場で泥臭いデータ移行を何度も経験してきたエンジニアです。
皆さんのデータベースに、Excelからインポートし続けた「何でも入り」の巨大なフラットテーブルはありませんか?列数が50を超え、更新するたびにロックがかかるような惨状……。これを手作業で分割するのは地獄の始まりです。
今日は、「VBAを使って、巨大なテーブルを正規化ルールに基づいて自動分割し、リレーションまで再構築する」という、エンジニア冥利に尽きる技術をお教えします。
—
1. なぜ「VBAで正規化」が必要なのか?
手作業でのコピペはミスを招きます。また、AccessのUIで何度も作業するのは非効率です。
VBAで制御する最大のメリットは「再現性と検証」です。失敗したらテーブルを消して、もう一度スクリプトを走らせればいい。この「やり直しが効く環境」こそが、大規模改修の成功の鍵です。
—
2. 自動化エンジンの全体像:3つのステップ
1. 設計(設計図の作成): どの列をどのテーブルに移動させるかを定義します。
2. 生成(DDLの実行): `TableDef` オブジェクトを操作し、新しいテーブルを生成します。
3. 転送(データ移行): `INSERT INTO` クエリでデータを流し込み、最後にリレーションを貼ります。
—
3. 実践:テーブル分割エンジン(サンプルコード)
今回は、顧客情報と注文情報が混在した `T_Master` から、正規化された `T_Customer` を切り出すコードを紹介します。
Public Sub SplitTableEngine()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Set db = CurrentDb
‘ 1. 新しいテーブル(T_Customer)を定義して作成
On Error Resume Next
db.TableDefs.Delete “T_Customer” ‘ 既存なら削除してリセット
On Error GoTo 0
Set tdf = db.CreateTableDef(“T_Customer”)
‘ フィールドの定義(主キーの設定など)
With tdf
.Fields.Append .CreateField(“CustomerID”, dbLong)
.Fields.Append .CreateField(“CustomerName”, dbText, 255)
.Fields.Append .CreateField(“Phone”, dbText, 20)
End With
db.TableDefs.Append tdf
‘ 2. データ移行(DISTINCTを使って重複を除去するのが正規化の極意)
Dim strSQL As String
strSQL = “INSERT INTO T_Customer (CustomerID, CustomerName, Phone) ” & _
“SELECT DISTINCT CustomerID, CustomerName, Phone FROM T_Master;”
db.Execute strSQL, dbFailOnError
‘ 3. リレーションシップの再構築
Dim rel As DAO.Relation
Set rel = db.CreateRelation(“FK_Order_Customer”, “T_Customer”, “T_Orders”)
rel.Fields.Append rel.CreateField(“CustomerID”)
rel.Fields(“CustomerID”).ForeignName = “CustomerID”
db.Relations.Append rel
MsgBox “正規化完了!世界が整いました。”
End Sub
—
4. ここがプロのこだわり:陥りやすい罠と対策
① 「レコードセットの開けっ放し」問題
VBAで大量のデータを扱う際、`Recordset` を開いたままループを回すとメモリを食いつぶします。「データ移行はなるべくSQL(INSERT INTO)で一括処理する」のが鉄則です。VBAは「SQLを組み立てる司令塔」に徹しましょう。
② 「主キーの欠落」を許すな
フラットテーブルのデータには、ゴミデータが含まれていることが多いです。`DISTINCT` キーワードをSQLに含めることで、重複を排除し、正規化後のテーブルの整合性を保つことができます。
③ エラーハンドリングの重要性
`TableDef` を操作する際、既にテーブルが存在しているとエラーで止まります。`On Error Resume Next` を活用し、存在確認と削除のロジックを必ず組み込んでください。
—
5. 初心者が「伝説のエンジニア」へ進むために
このコードは、まさに「テーブルの構造をコードで支配する」ための第一歩です。
- まずは真似る: 上記コードを新しいAccessファイルで動かしてみてください。
- 構造を理解する: `db.TableDefs` や `db.Relations` が、Accessというデータベースの「背骨」であることを意識してください。
- 次に繋げる: これができれば、次は「フィールドのデータ型を自動判定してマイグレーションする」といった高度な自動化にも挑戦できます。
「Access VBAは古い」なんて言う人もいますが、現場のレガシーシステムを劇的に改善できるのは、この言語を知り尽くした者だけです。
ここをクリアすれば、あなたはもうマクロの記録ボタンを押して悩むだけのユーザーではありません。「データベースを自在に操る設計者」です。一歩ずつ、着実に進んでいきましょう!
何か詰まったら、いつでも聞いてください。応援しています。
