Enum(列挙型)とは
VBAでステータスや区分を数値で管理していると、「1が未処理で、2が処理中で、3が完了……」といった意味をコードのあちこちで覚えておかなければならず、コードを読むたびに「この2ってどういう意味だっけ?」と迷ってしまうことがあります。このような、意味の分かりにくい数値のことを「マジックナンバー」と呼びます。
Enum(列挙型)を使うと、こうした数値に名前を付けて管理できるようになり、コードの可読性が大きく向上します。この記事では、Enumの基本的な使い方から、Select Caseや関数の引数との組み合わせ、実務での活用例までを解説します。
マジックナンバーの問題点
まずは、数値をそのまま使ったコードの例を見てみましょう。
Sub CheckStatus(status As Long)
If status = 1 Then
Debug.Print "未処理です"
ElseIf status = 2 Then
Debug.Print "処理中です"
ElseIf status = 3 Then
Debug.Print "完了です"
End If
End Sub
このコードは動作こそ問題ありませんが、「1」「2」「3」が何を意味するのかはコードを追わないと分かりません。呼び出す側でもCheckStatus 2のように数値を直接書くことになり、可読性・保守性の面で不安が残ります。
基本構文
Enumは、モジュールの宣言セクション(プロシージャの外側)で以下のように定義します。
Enum StatusType
Mikanryo = 1
Shorichu = 2
Kanryo = 3
End Enum
何も値を指定しない場合は、先頭の要素が自動的に0になり、以降は1つずつ増えていきます。
Enum ColorType
ColorRed '0
ColorBlue '1
ColorGreen '2
End Enum
Enumを使った書き換え
先ほどのCheckStatusプロシージャを、Enumを使って書き換えてみます。
Enum StatusType
Mikanryo = 1
Shorichu = 2
Kanryo = 3
End Enum
Sub CheckStatus(status As StatusType)
Select Case status
Case Mikanryo
Debug.Print "未処理です"
Case Shorichu
Debug.Print "処理中です"
Case Kanryo
Debug.Print "完了です"
End Select
End Sub
Sub CallCheckStatusSample()
CheckStatus Kanryo '→ 完了です
End Sub
引数の型をStatusTypeにしておくことで、呼び出す側はCheckStatus 3ではなくCheckStatus Kanryoと書けるようになり、コードの意図が一目で分かるようになります。VBEの入力補完(インテリセンス)でも候補として表示されるため、タイプミスによる存在しない値の入力も防げます。
関数の戻り値の型として使う
Enumは引数だけでなく、Functionの戻り値の型としても利用できます。
Function GetStatusFromCell(cellValue As String) As StatusType
Select Case cellValue
Case "未処理"
GetStatusFromCell = Mikanryo
Case "処理中"
GetStatusFromCell = Shorichu
Case "完了"
GetStatusFromCell = Kanryo
Case Else
GetStatusFromCell = Mikanryo
End Select
End Function
Sub CallGetStatusSample()
Dim st As StatusType
st = GetStatusFromCell(Range("A1").Value)
If st = Kanryo Then
Debug.Print "この行は完了しています"
End If
End Sub
セルの文字列をEnum型の値に変換しておくことで、以降の処理では数値や文字列を意識せず、意味の分かる定数名だけで条件分岐を書けるようになります。
Const(定数)との違い
「名前に意味を持たせる」という点では、Constを使った定数宣言と似ていますが、Enumには以下のような違いがあります。
| Enum | Const | |
|---|---|---|
| 複数の値をまとめられるか | まとめて1つの型として定義できる | 1つずつ個別に宣言する必要がある |
| 型として使えるか | 引数や戻り値の型として指定できる | 型としては使えない(あくまで値) |
| 入力補完 | 型を指定すればVBEの候補に表示される | 候補には表示されない |
| 用途 | 区分・状態・種類などのグループを表す | 単発の固定値(税率・上限件数など) |
「関連する複数の状態や区分をまとめて管理したい」場合はEnum、「1つの固定値に名前を付けたいだけ」の場合はConstを使う、という使い分けが基本になります。
実践例:進捗ステータスに応じてセルに色を付ける
Enumを使うことで、シートの進捗管理マクロも読みやすく書けます。
Enum StatusType
Mikanryo = 1
Shorichu = 2
Kanryo = 3
End Enum
Sub ColorByStatus()
Dim c As Range
Dim st As StatusType
For Each c In Range("B2:B10")
Select Case c.Value
Case 1: st = Mikanryo
Case 2: st = Shorichu
Case 3: st = Kanryo
End Select
Select Case st
Case Mikanryo
c.Interior.Color = RGB(255, 199, 199)
Case Shorichu
c.Interior.Color = RGB(255, 235, 156)
Case Kanryo
c.Interior.Color = RGB(198, 239, 206)
End Select
Next c
End Sub
セルの数値をいったんEnum型の変数に変換してから色分けの分岐を書くことで、「1が何色を意味するのか」がコードを見ただけで分かるようになります。
注意点
- 同じモジュール内、または他のモジュールで同名のEnumメンバー(要素名)を重複して定義するとコンパイルエラーになります。命名時は他の変数名や定数名と被らないよう注意してください。
- Enumはあくまで内部的にはLong型の数値として扱われるため、
status = 1のように直接数値を代入することも可能です。可読性を保つためには、必ずEnumの要素名を使って値を設定・比較する運用を徹底することが大切です。 - 標準モジュールの宣言セクションに書く必要があり、プロシージャの内部で宣言することはできません。
まとめ
Enum(列挙型)を使うと、数値の意味をコードの中に明示できるため、マジックナンバーによる可読性の低下を防げます。Select Caseとの組み合わせや、引数・戻り値の型として指定することで、呼び出し側にも意図が伝わりやすいコードになります。ステータス管理や区分管理を数値だけで行っているコードがあれば、ぜひEnumへの置き換えを検討してみてください。


コメント