こんにちは!Access VBAの世界へようこそ。
システム開発の現場で「なんだか最近、Accessのファイルサイズ(.accdb)がやたらと膨らんできたぞ……」と頭を抱えた経験はありませんか?
データ件数はそこまで爆発的に増えていないのに、なぜかファイルが重い。その原因の多くは、テキスト型フィールドの「Unicode圧縮」プロパティのデフォルト設定にあります。
今回は、この「Unicode圧縮」をVBAで自在に操り、データベースのサイズを極限までスリム化するプロの技を伝授します。
「マクロの記録」から一歩抜け出して、本当の意味でAccessをコントロールする楽しさを味わってみましょう!ここをクリアすれば、あなたのVBAスキルは確実に中級者の領域に到達しますよ。
—
なぜAccessのファイルは肥大化するのか?(Unicode圧縮の正体)
Accessの「短いテキスト」型(旧バージョンでの「テキスト型」)フィールドには、「Unicode圧縮」というプロパティが存在します。
- Unicode圧縮とは?
英語や数字、記号といった「1バイトで表現できる文字」を保存する際、内部的に余分なバイト(00のデータ)を削って容量を節約する機能です。
- 何が問題なのか?
実は、Accessのテーブルを新規作成した際、フィールドの種類や設定によっては、このUnicode圧縮が「いいえ」になっているケースや、後から追加したフィールドで意図せずオフになっていることがあります。
特に、社員マスタや商品マスタなどで「半角の英数字や記号」を大量に保存している場合、Unicode圧縮が効いていないと、ファイルサイズが無駄に2倍近く膨れ上がります。
とはいえ、数十個、数百個あるフィールドのプロパティを、テーブルデザイン画面を開いて一つひとつ「はい」に変更していく……なんて作業は、エンジニアのやる仕事ではありませんよね。そう、VBAで一括自動化してしまいましょう!
—
現場で使える!全テーブル・全フィールド最適化スクリプト
それでは早速、データベース内のすべてのテーブルを走査し、テキスト型フィールドの「Unicode圧縮」を強制的に「True(はい)」に書き換える実用コードを公開します。
標準モジュールに貼り付けて、そのまま実行できるように設計しました。
Sub OptimizeUnicodeCompression()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim updatedCount As Long
‘ 現在のアクティブなデータベースを参照
Set db = CurrentDb
updatedCount = 0
On Error GoTo ErrorHandler
‘ データベース内のすべてのテーブルをループ
For Each tdf In db.TableDefs
‘ システムテーブル(MSysで始まるもの)やリンクテーブルは除外する
If (tdf.Attributes & dbSystemObject) = 0 And (tdf.Attributes & dbAttachedTable) = 0 Then
‘ テーブル内のすべてのフィールドをループ
For Each fld In tdf.Fields
‘ フィールドのデータ型が「テキスト型(dbText)」であるか判定
If fld.Type = dbText Then
‘ エラーハンドリング:Unicode圧縮をサポートしていないプロパティへの配慮
On Error Resume Next
‘ Unicode圧縮プロパティを True (はい) に設定
fld.Properties(“UnicodeCompression”) = True
If Err.Number = 0 Then
updatedCount = updatedCount + 1
Debug.Print “最適化成功: [” & tdf.Name & “].[” & fld.Name & “]”
End If
On Error GoTo ErrorHandler
End If
For Next fld
End If
Next tdf
‘ 完了メッセージ
MsgBox “処理が完了しました!” & vbCrLf & _
“合計 ” & updatedCount & ” 個のフィールドをUnicode圧縮しました。”, _
vbInformation, “容量最適化ツール”
Exit_Routine:
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
Resume Exit_Routine
End Sub
—
コードの解説:ここがプロのポイント!
このコードには、Access VBAを扱う上で知っておくべき「安全に動かすための知恵」が詰まっています。ポイントを3つに分けて解説しますね。
1. システムテーブルとリンクテーブルの「除外」
Accessの内部には、`MSysObjects` のようなシステムが管理する隠しテーブルが存在します。これらを触ろうとすると、容赦なくエラー(権限エラーなど)が発生します。
また、外部のSQL Serverや別のAccessファイルを参照している「リンクテーブル」のプロパティはローカル側から変更できません。
そのため、`tdf.Attributes` をチェックして、純粋なローカル・テーブルだけをターゲットに絞り込んでいるのがスマートなポイントです。
2. データ型の厳密な判定 (`fld.Type = dbText`)
数あるフィールドの中から、「短いテキスト型」だけに絞るために `dbText` 定数を使用しています。数値型や日付型、メモ型(長テキスト型)に誤ってUnicode圧縮プロパティを設定しようとすると、エラーを引き起こすため、このフィルタリングが極めて重要です。
3. DAOプロパティの動的追加とエラー回避
AccessのDAO(Data Access Objects)では、フィールドのプロパティ(今回で言う `UnicodeCompression`)は、最初からコレクションに存在しない場合があります。
そのため、`On Error Resume Next` を巧妙に挟み込み、「もしそのプロパティが存在して変更できればラッキー、ダメならスキップ」という堅牢な(ロバストな)構造にしています。
—
陥りやすい罠と注意点(ここだけは押さえよう!)
初学者がこのテーマでつまずきやすいポイントをいくつか先回りして解説しておきます。
- 「長テキスト型(memo型)」との混同に注意
Access 2016以降の新しい「長テキスト型(旧メモ型)」には、実はUnicode圧縮という概念はありません(内部で常にUTF-16等で効率よく保持されるため)。今回のコードは「短いテキスト型(dbText)」に特化しているため問題ありませんが、型ごとの仕様の違いを意識しておきましょう。
- 実行するだけではファイルサイズは小さくならない!?(超重要)
ここが一番の罠です。VBAを実行してフィールドの設定を変更しても、Accessの物理的なファイルサイズはすぐには小さくなりません。
Accessはデータを削除したり圧縮設定を変えたりしても、内部の領域(空きスペース)を保持し続ける性質があります。
サイズを実際に削るためには、コードを実行したあとに、[データベースツール] > [データベースの最適化と修復] を手動で行うか、VBAから `DBEngine.CompactDatabase` を実行する必要があります。
—
まとめ:Access VBAでDBを「軽く、速く」操ろう!
今回は、フィールドの「Unicode圧縮」プロパティをVBAで一括制御し、データベースの容量を最適化する手法を解説しました。
- GUIでの手作業から脱却し、`TableDefs` と `Fields` コレクションをループさせる。
- システムテーブルやリンクテーブルを的確に除外する。
- 最後に「データベースの最適化と修復」を行い、物理容量をスリムにする。
この一連の流れをマスターすれば、何GBにも膨れ上がった重いAccessシステムも、あなたの手一つで軽快な動作へと蘇らせることができます。
「動くだけのコード」から「システムを最適化できるエンジニア」へ。
今回のテクニックをぜひ実際の開発現場で試してみてくださいね。応援しています!
