【入門編】【上級】大規模なテーブル分割(正規化)をVBAで自動化する移行スクリプト – Access VBA解析バイブル

スポンサーリンク

【上級】巨大なフラットテーブルを解体せよ: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は古い」なんて言う人もいますが、現場のレガシーシステムを劇的に改善できるのは、この言語を知り尽くした者だけです。

ここをクリアすれば、あなたはもうマクロの記録ボタンを押して悩むだけのユーザーではありません。「データベースを自在に操る設計者」です。一歩ずつ、着実に進んでいきましょう!

何か詰まったら、いつでも聞いてください。応援しています。

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