記事ID: 095
タイトル: Enumで定数グループを定義してコードを読みやすくする方法
カテゴリ: シート操作
一次キーワード: VBA Enum 定数 一覧
想定読者: VBAで条件分岐を使い始めた初心者〜初級者。コード中にマジックナンバーが増えて管理しづらくなっている人。
検索意図: VBAのEnum(列挙型)の書き方と使い方を知りたい。定数をグループ化してコードの可読性を上げたい。
読者の悩み(1文): コードの中に意味不明な数値(1, 2, 3...)が散らばっていて、後から見ると何の値か分からなくなる。
読了後にできること(1文): Enumで定数グループを定義し、マジックナンバーを意味のある名前に置き換えて、読みやすく保守しやすいコードが書ける。
前提条件:
- Excel版: Excel 2016以降 / Microsoft 365
- OS: Windows 10/11
- 保存形式: .xlsm(マクロ有効ブック)
- 貼り付け場所: 標準モジュール
- 実行方法: Alt+F8 → マクロ実行 / ボタン割り当て
更新日: 2026-03-18
—
この記事でわかること
- VBAのEnum(列挙型)で、関連する定数をグループにまとめて定義できる
If status = 1のようなマジックナンバーをIf status = stActiveに置き換えて読みやすくできる- Enum × Select Caseで実務の分岐処理をスッキリ書ける
対象: VBAで条件分岐を使い始めた人。コードの数値が何を意味するか分からなくなった経験がある人。
所要時間: コピペ → 実行まで約5分
—
どんな場面で使う?
- ステータスコード(承認済み・差し戻し・未処理など)をマジックナンバーでなく名前で管理したい
- Select Caseの分岐条件を数値でなく意味のある定数名で書いて可読性を上げたい
- 複数のConst定数をグループ化してまとめて管理したい
- セルの色分け処理で色定数をEnumにまとめて管理したい—
完成イメージ(Before / After)
Before(マジックナンバーだらけのコード):
If status = 1 Then
MsgBox "有効"
ElseIf status = 2 Then
MsgBox "休止"
ElseIf status = 3 Then
MsgBox "終了"
End If
→ 1, 2, 3 が何を意味するのか、コードだけでは分からない。
After(Enumで名前を付けたコード):
If status = stActive Then
MsgBox "有効"
ElseIf status = stSuspended Then
MsgBox "休止"
ElseIf status = stClosed Then
MsgBox "終了"
End If
→ stActive, stSuspended, stClosed で意味が一目でわかる。
—
自分も以前、Select CaseやIfの分岐で Case 1, Case 2 のように数値を直接書いていた。3か月後に見返したとき「この1って何だっけ?」と自分のコードなのに意味が分からなくなった。正直しんどかった。Enumで定数に名前を付けてからは、コードを読み返すときに一瞬で意味が分かるようになった。修正も怖くなくなった。マジックナンバーだらけのコードで苦しんでいる人が、この記事でEnumを知ってスッキリ書けるようになればうれしい。
Enumを使えば、関連する定数をグループにまとめて名前を付けられる。マジックナンバーが消えて、コードの可読性が格段に上がる。
なお、Select Caseの基本的な書き方は Select Caseで複数条件の分岐をスッキリ書く方法 を参照。この記事はその発展として、Enumで定数を管理する方法を扱う。
—
実行前の準備
バックアップを取る
実務版コードはセルの値を書き換える。必ずファイルのコピーを別フォルダに保存してから実行する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
重要: Enum定義はSubプロシージャの外(モジュールの先頭付近)に書く。Sub の中には書けない。
補足: 基本版と実務版を同じモジュールに貼る場合、
Option Explicitは先頭に1回だけ書く(重複するとエラーになる)。
—
コード(基本版)– Enumでステータスコードを定義して分岐する
まずはこれで動きを確認する。ステータスコード(1=有効, 2=休止, 3=終了)をEnumで定義し、セルA1の値に応じてMsgBoxで表示する。
セルA1に数値(1, 2, 3のいずれか)を入力してから実行してください。 空セルや文字列が入っているとエラーになる。
Option Explicit
'============================================================
' ■ ステータスコードのEnum定義
' → 関連する定数をグループにまとめる
' → Subの外(モジュールレベル)に書く
'============================================================
Public Enum StatusCode
stActive = 1 '有効
stSuspended = 2 '休止
stClosed = 3 '終了
End Enum
'============================================================
' ■ ステータス判定(基本版)
' → セルA1の値をEnum定数で分岐してMsgBox表示
'============================================================
Sub JudgeStatus()
Dim currentStatus As StatusCode
currentStatus = CLng(Range("A1").Value) '← セルA1の値を取得
Select Case currentStatus
Case stActive
MsgBox "ステータス: 有効", vbInformation
Case stSuspended
MsgBox "ステータス: 休止", vbExclamation
Case stClosed
MsgBox "ステータス: 終了", vbInformation
Case Else
MsgBox "不明なステータス: " & currentStatus, vbCritical
End Select
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
Range("A1") |
ステータスコードが入っているセル | A1 |
stActive = 1 |
有効のコード番号 | 1 |
stSuspended = 2 |
休止のコード番号 | 2 |
stClosed = 3 |
終了のコード番号 | 3 |
ポイント: Select Case currentStatus で分岐すると、Case節にEnumメンバー名が並ぶので意味が一目でわかる。Case 1, Case 2 と書くよりはるかに読みやすい。
MsgBoxの使い方の詳細は MsgBoxで確認ダイアログを出して処理を分岐する方法 を参照。
—
Enumの基本ルール(これだけ押さえればOK)
構文
Public Enum 列挙型名
メンバー名1 [= 値]
メンバー名2 [= 値]
...
End Enum
ルール一覧
| ルール | 内容 |
|---|---|
| 値の型 | Long型のみ(文字列は不可) |
| 自動採番 | 値を省略すると、最初のメンバーが0、以降+1 |
| 明示指定 | メンバー名 = 値 で好きな数値を指定できる |
| スコープ | 標準モジュールでPublic(既定)なら全モジュールから参照可能 |
| 入力補完 | Enum型変数に対してIntelliSense(Ctrl+Space)で候補が出る |
| 定義場所 | Subの外(モジュールレベル)に書く。Subの中には書けない |
自動採番の例
Public Enum Priority
prLow '← 0(自動)
prMedium '← 1(自動)
prHigh '← 2(自動)
prCritical = 10 '← 10(明示指定)
prEmergency '← 11(10の次で自動)
End Enum
—
コード(実務版)– Enum × Select Case × RGB色でセル処理
Enumで色定数をまとめてからは、RGB値を毎回調べる手間がなくなった。月次報告の部門別集計で使っていて、チームにマクロを渡すときも「ここのEnum定義を見れば色が分かる」と説明できるようになった。
A列に部門コード(数値)が入った一覧表を処理する。部門コードをEnumで定義し、Select Caseで分岐して、B列に部門名を書き込み、セルの背景色をEnum定義した色で設定する。
※ B列の既存データとセルの背景色は上書きされます。実行前にバックアップを取ってください。
Option Explicit
'============================================================
' ■ 部門コードのEnum定義
'============================================================
Public Enum DeptCode
deptSales = 1 '営業部
deptAdmin = 2 '管理部
deptFactory = 3 '製造部
deptQuality = 4 '品質管理部
End Enum
'============================================================
' ■ セル背景色のEnum定義(RGB値をLong型で格納)
' → VBAのRGB関数は R + G*256 + B*65536 でLong値を返す
' → そのLong値をEnumメンバーの値として定義する
'============================================================
Public Enum CellColor
clrLightBlue = 16237469 'RGB(157, 195, 247) — 薄い青
clrLightGreen = 11002054 'RGB(198, 224, 167) — 薄い緑
clrLightOrange = 10277626 'RGB(250, 210, 156) — 薄いオレンジ
clrLightPurple = 16233433 'RGB(217, 179, 247) — 薄い紫
clrLightGray = 14277081 'RGB(217, 217, 217) — 薄いグレー
clrWhite = 16777215 'RGB(255, 255, 255) — 白
End Enum
'============================================================
' ■ 部門コード→部門名+色設定(実務版)
' → A列: 部門コード(数値)
' → B列: 部門名を書き込み、セル背景色を設定
' → 対象シート: アクティブシート
'============================================================
Sub ClassifyDepartment()
'--- ★書き換えポイント ---
Dim startRow As Long: startRow = 2 '← データ開始行
Dim codeCol As Long: codeCol = 1 '← 部門コード列(A列)
Dim nameCol As Long: nameCol = 2 '← 部門名書き込み列(B列)
'--- ★ここまで ---
Dim ws As Worksheet
Set ws = ActiveSheet
'--- 最終行を取得 ---
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, codeCol).End(xlUp).Row
If lastRow < startRow Then
MsgBox "データがありません。A列に部門コードを入力してください。", vbExclamation
Exit Sub
End If
'--- エラー処理 ---
On Error GoTo ErrHandler
Dim r As Long
Dim processCount As Long: processCount = 0
Dim rawValue As Variant
Dim dept As DeptCode
Dim deptName As String
Dim bgColor As CellColor
For r = startRow To lastRow
rawValue = ws.Cells(r, codeCol).Value
'--- 空セル・非数値はスキップして次の行へ ---
If IsEmpty(rawValue) Or Not IsNumeric(rawValue) Then
ws.Cells(r, nameCol).Value = "(コード未入力)"
ws.Cells(r, nameCol).Interior.Color = clrLightGray
GoTo NextRow
End If
dept = CLng(rawValue)
'--- Enum × Select Case で分岐 ---
Select Case dept
Case deptSales
deptName = "営業部"
bgColor = clrLightBlue
Case deptAdmin
deptName = "管理部"
bgColor = clrLightGreen
Case deptFactory
deptName = "製造部"
bgColor = clrLightOrange
Case deptQuality
deptName = "品質管理部"
bgColor = clrLightPurple
Case Else
deptName = "不明(コード: " & dept & ")"
bgColor = clrWhite
End Select
ws.Cells(r, nameCol).Value = deptName
ws.Cells(r, nameCol).Interior.Color = bgColor
processCount = processCount + 1
NextRow:
Next r
MsgBox processCount & " 行の部門名と背景色を設定しました。", vbInformation
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました。" & vbCrLf & _
"行: " & r & vbCrLf & _
"エラー: " & Err.Description, vbCritical
End Sub
エラー処理の基本は エラー処理(On Error)で止まらないマクロを作る方法 を参照。
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
startRow |
データの開始行 | 2(1行目はヘッダー) |
codeCol |
部門コードの列 | 1(A列) |
nameCol |
部門名の書き込み列 | 2(B列) |
DeptCode のメンバー |
部門コードの番号 | 自社のコード体系に合わせて変更 |
CellColor のメンバー |
背景色のRGB値 | 好みの色に変更(VBAのイミディエイトウィンドウで ?RGB(R,G,B) を実行するとLong値がわかる) |
シート構成の例
| A列(部門コード) | B列(部門名)← マクロで書き込み |
|---|---|
| 1 | 営業部(薄い青) |
| 2 | 管理部(薄い緑) |
| 3 | 製造部(薄いオレンジ) |
| 4 | 品質管理部(薄い紫) |
| 9 | 不明(コード: 9)(白) |
RGB色の操作方法の詳細は セルの背景色・文字色をRGBで自由に操作する方法 を参照。
Enumで定義した部門コードを引数にして別のマクロに渡すこともできる。やり方は マクロから別のマクロを呼び出して処理を分割する方法 を参照。
—
よくある落とし穴5選
1. Enumメンバー名に予約語を使ってコンパイルエラー
自分もこれでハマった。Enumのメンバー名に「End」と付けたら予約語と衝突して コンパイルエラー: 構文エラー になった。エラーメッセージには「予約語です」とは出ないので、原因に気づくまで20分は溶かした。
| 症状 | 原因 | 対策 |
|---|---|---|
| コンパイルエラー: 構文エラー | メンバー名にVBA予約語(End, Sub, If, For, Type, Setなど)を使った | プレフィックスを付ける(stEnd → stCompleted)か別の単語に変える |
2. 値を省略して0始まりになり、業務コードとずれる
| 症状 | 原因 | 対策 |
|---|---|---|
| Enumの値と業務コードが合わない | 値を省略すると最初のメンバーが0から始まる | 業務コードに合わせて メンバー = 値 で明示的に指定する |
' NG: 0始まりで業務コード(1始まり)とずれる
Public Enum DeptCode
deptSales '← 0 になる(期待は1)
deptAdmin '← 1 になる(期待は2)
End Enum
' OK: 明示的に値を指定
Public Enum DeptCode
deptSales = 1
deptAdmin = 2
End Enum
3. 別のEnumで同名メンバーを作って名前衝突
| 症状 | 原因 | 対策 |
|---|---|---|
| コンパイルエラー、または意図しないメンバーが参照される | Public Enumのメンバーはグローバルスコープで公開される | メンバー名にプレフィックスを付ける(clrRed, deptSales) |
4. シートモジュールにEnumを書いて他から参照できない
| 症状 | 原因 | 対策 |
|---|---|---|
| 他のモジュールからEnumメンバーを使うとコンパイルエラー | シートモジュールのEnumは暗黙的にPrivateになる | Enumは標準モジュールに書く |
5. Enum型変数に範囲外の値を入れてもエラーにならない
| 症状 | 原因 | 対策 |
|---|---|---|
| 未定義の値(例: 999)が入ってもエラーなく動いてしまう | VBAのEnumは内部的にLong型で、型チェックが緩い | Select CaseのCase Elseで想定外の値を検知する |
—
VBAのEnumでコンパイルエラーが出るときの対処法
「Enum定義を書いたらコンパイルエラーになる」という場合、原因はメンバー名にVBAの予約語(Error, Name, Typeなど)を使っていることが多い。予約語と重複しない名前(例:errStatus → StatusError)に変更すること。
VBAのEnum値がシート間で共有できないときの対処法
「シートモジュールにEnumを定義したら他のモジュールから参照できない」という場合、原因はシートモジュールに定義したEnumはそのモジュール内でしか使えないためだ。全体で共有するEnumは標準モジュールの先頭に定義すること。
FAQ
Q1: EnumとConstはどう使い分ける?
| 使い分け | Enum | Const |
|---|---|---|
| 用途 | 関連する定数をグループ化 | 単独の定数を定義 |
| 値の型 | Long型のみ | 文字列・数値・日付など |
| 入力補完 | Enum型変数にドットでメンバー候補が出る | 補完なし |
| おすすめ場面 | 状態コード、部門コード、色コードなど | ファイルパス、シート名など |
結論: 「意味的にグループになる数値定数」はEnum、「単独の設定値や文字列定数」はConst。
Q2: Enumの値に文字列は使える?
使えない。VBAのEnumはLong型の整数のみ。文字列定数を定義したい場合は Const を使う。
' これはNG(文字列は指定できない)
Public Enum SheetName
shMain = "メイン" '← コンパイルエラー
End Enum
' 文字列はConstで定義する
Public Const SHEET_MAIN As String = "メイン"
Q3: VBAの組み込み定数(vbOK, vbRedなど)もEnum?
そのとおり。VBAに最初から入っている定数の多くはEnumで定義されている。
vbOK = 1,vbCancel = 2→VbMsgBoxResultEnumvbRed,vbBlue→ColorConstantsEnumxlUp,xlDown→XlDirectionEnum
自分で作るEnumも、これらと同じ仕組み。
Q4: Enumのメンバーを後から追加しても大丈夫?
大丈夫。End Enumの手前に新しいメンバー行を追加するだけ。既存のコードが壊れることはない(Case Elseを入れておけば、新しい値が来ても想定外として検知できる)。
Q5: Enumの全メンバーをループで取得できる?
VBAにはEnum全メンバーを動的に列挙する機能がない(VB.NETの Enum.GetValues のような機能は非対応)。対策は2つ。
- Enum定義にコメントで一覧を書いておく
- メンバーの最小値・最大値を定義してForループで回す
Public Enum DeptCode
deptMin = 1 '← ループ用の最小値
deptSales = 1 '← deptMinと同じ値でもOK(動作に問題なし)
deptAdmin = 2
deptFactory = 3
deptQuality = 4
deptMax = 4 '← ループ用の最大値
End Enum
' ループで全メンバーを処理
Dim d As Long
For d = deptMin To deptMax
Debug.Print d
Next d
—
まとめ
- Enum: 関連する定数をグループにまとめて名前を付けられる
- マジックナンバーの排除:
Case 1→Case stActiveで意味が一目でわかる - Select Caseとの相性: Enum × Select Caseで分岐処理がスッキリ書ける
- 値はLong型のみ: 文字列定数はConstを使う
- Case Elseは必須: Enum型変数に範囲外の値が入ってもエラーにならないため、自分で検知する
もっと早く知りたかったと思う機能の1つ。Enumを使い始めると、マジックナンバーだらけだった過去の自分のコードが別物に見える。
関連記事
- Select Caseで複数条件の分岐をスッキリ書く方法 — Enum × Select Caseの相性が良い
- MsgBoxで確認ダイアログを出して処理を分岐する方法 — Enum判定結果の表示に使える
- セルの背景色・文字色をRGBで自由に操作する方法 — Enum × RGBで色定数を管理する
- マクロから別のマクロを呼び出して処理を分割する方法 — Enum定数を引数にして渡す
- エラー処理(On Error)で止まらないマクロを作る方法 — 実務版のエラーハンドリング
—
次にやりたくなること
- Select Caseで複数条件の分岐をスッキリ書く方法: Enumで定義した定数をSelect Caseで使えば、分岐処理がさらに読みやすくなる
- セルの背景色・文字色をRGBで自由に操作する方法: Enumで色定数をまとめて管理し、セルの色設定をもっと自在にしたい場合
- マクロから別のマクロを呼び出して処理を分割する方法: Enum定数を引数にして別マクロに渡し、処理を分割して整理したい場合


コメント