【ExcelVBA・マクロ】Enum(列挙型)の使い方|マジックナンバーをなくして読みやすいコードにする方法【コピペOK】

ExcelVBA

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への置き換えを検討してみてください。

スポンサーリンク
スポンサーリンク
ExcelVBA
シェアする
いがぴをフォローする

コメント

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