Enum(列挙型)とは
Enum(列挙型)は、自動で1ずつ増える連番を振られた定数の集まりのことです。
連番の開始値は0になりますが、任意の値を開始値にすることも可能です。マイナス値もOKです。
構文
[ Public | Private ] Enum 列挙型名
定数名 [= 値または式]
定数名 [= 値または式]
・
・
End Enum
Public、Private(省略可) | Enum宣言をVBAProject全体で利用したい場合はPublicを指定します。Enumを宣言しているモジュール内でのみ利用したい場合はPrivateを指定します。PublicとPrivateを同時に設定することはできません。省略時はPublic扱いになります。 |
列挙型名 | Enum型の名前を指定します。 |
定数名 | 定数名を指定します。複数指定する場合はより上から下に向かって連番が設定されます。 |
値または式(省略可) | 定数に設定する値を指定します。省略時は直前の定数値+1が設定されます。先頭の定数を省略した場合は0が設定されます。 |
Enum(列挙型)の用途
Enumの定数の値は自由に設定できます。ただ、設定しすぎるとEnumの特性である「連番の自動付与」を捨てることになり、そうなってくるとEnumを使う意味が薄れてきます。
Enum(列挙型)の用途は、なにかしら連続する値の集まりであることがはっきりわかっている場合や、定数のグループとして扱える場合などがあります。そのため、連番や意味ある数値である必要性がない場合の利用には不向きです。そのような場合は通常の定数(Const)を利用した方がよいでしょう。
以降ではコードと一緒にExcelでEnumを使う用途として考えられるものを2つ紹介します。
1つはシートの列の位置を示す使い方で、もう1つはデータ値の性格を示す使い方です。
シートの列の位置を示す列挙型
以下のようにシートに表形式のデータがある場合に、A~D列を示す列挙型を用意します。
1 2 3 4 5 6 |
Private Enum 表の列位置 No = 1 日付 '// 連番で2が自動で設定される 個数 '// 連番で3が自動で設定される メモ '// 連番で4が自動で設定される End Enum |
先頭の「No」にだけ1を設定しています。これは、RangeオブジェクトではA列の位置を1として扱うためです。「Range(“A1”)」や「Cells(1, 1)」と書いた場合はA1セルを意味します。
「No」が1のため、以降の「日付」には2、「個数」には3、「メモ」には4が定数値として設定されます。
以下のコードは表の内容をイミディエイトウィンドウに出力しています。1行ずつループして、各列の内容を出力しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
Private Enum 表の列位置 No = 1 日付 '// 連番で2が自動で設定される 個数 '// 連番で3が自動で設定される メモ '// 連番で4が自動で設定される End Enum Type 表 No As String 日付 As String 個数 As String メモ As String End Type Sub 表データ取得() Dim r As Range Dim h As 表 '// No列の先頭行を基点セルに設定 Set r = Cells(1, 表の列位置.No) Do If r.Value = "" Then Exit Do End If '// 構造体に各列の値を設定 h.No = r.Value h.日付 = r.Offset(0, 表の列位置.日付 - 1) h.個数 = r.Offset(0, 表の列位置.個数 - 1) h.メモ = r.Offset(0, 表の列位置.メモ - 1) Debug.Print r.Row & "行目:" & 表の列位置.No & "列目:No=" & h.No Debug.Print r.Row & "行目:" & 表の列位置.日付 & "列目:日付=" & h.日付 Debug.Print r.Row & "行目:" & 表の列位置.個数 & "列目:個数=" & h.個数 Debug.Print r.Row & "行目:" & 表の列位置.メモ & "列目:メモ=" & h.メモ '// 次の行を基点セルに設定 Set r = r.Offset(1, 0) Loop End Sub |
実行結果
1行目:1列目:No=No
1行目:2列目:日付=日付
1行目:3列目:個数=個数
1行目:4列目:メモ=メモ
2行目:1列目:No=1
2行目:2列目:日付=2023/03/01
2行目:3列目:個数=1
2行目:4列目:メモ=あああああああ
3行目:1列目:No=2
3行目:2列目:日付=2023/03/02
3行目:3列目:個数=22
3行目:4列目:メモ=いいいいいい
4行目:1列目:No=3
4行目:2列目:日付=2023/03/03
4行目:3列目:個数=333
4行目:4列目:メモ=うううう
列の追加があっても定数値やコードを変更しなくてよい
もし、表の構成が変わって「日付」と「個数」の間に新しい列が追加された場合はEnumにも追加すると、以降の項目の定数値も変わります。この利点は、Enumの定数自体も定数を利用しているソースコードも書き換える必要がなくなる点です。列の位置がどこなのかはEnumの連番が指定してくれているので、気にしなくてよくなります。これがEnumを列位置に使う利点です。
上のコードに列が追加された場合、コードの中で変更が必要になるのは下の★マークを付けている箇所だけです。★マークの部分は追加列の処理のため、元々のコードには一切変更が入っていませんが、列が追加されて1ずつずれていてもEnumが連番を再振りしているので影響はありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
Private Enum 表の列位置 No = 1 日付 '// 連番で2が自動で設定される 追加列 '// ★列追加★連番で3が自動で設定される 個数 '// 連番で4が自動で設定される メモ '// 連番で5が自動で設定される End Enum Type 表 No As String 日付 As String 追加列 As String '// ★処理追加 個数 As String メモ As String End Type Sub 表データ取得() Dim r As Range Dim h As 表 '// No列の先頭行を基点セルに設定 Set r = Cells(1, 表の列位置.No) Do If r.Value = "" Then Exit Do End If '// 構造体に各列の値を設定 h.No = r.Value h.日付 = r.Offset(0, 表の列位置.日付 - 1) h.追加列 = r.Offset(0, 表の列位置.追加列 - 1) '// ★処理追加 h.個数 = r.Offset(0, 表の列位置.個数 - 1) h.メモ = r.Offset(0, 表の列位置.メモ - 1) Debug.Print r.Row & "行目:" & 表の列位置.No & "列目:No=" & h.No Debug.Print r.Row & "行目:" & 表の列位置.日付 & "列目:日付=" & h.日付 Debug.Print r.Row & "行目:" & 表の列位置.追加列 & "列目:追加列=" & h.追加列 '// ★処理追加 Debug.Print r.Row & "行目:" & 表の列位置.個数 & "列目:個数=" & h.個数 Debug.Print r.Row & "行目:" & 表の列位置.メモ & "列目:メモ=" & h.メモ '// 次の行を基点セルに設定 Set r = r.Offset(1, 0) Loop End Sub |
実行結果
1行目:1列目:No=No
1行目:2列目:日付=日付
1行目:3列目:追加列=追加列
1行目:4列目:個数=個数
1行目:5列目:メモ=メモ
2行目:1列目:No=1
2行目:2列目:日付=2023/03/01
2行目:3列目:追加列=追加A
2行目:4列目:個数=1
2行目:5列目:メモ=あああああああ
3行目:1列目:No=2
3行目:2列目:日付=2023/03/02
3行目:3列目:追加列=追加B
3行目:4列目:個数=22
3行目:5列目:メモ=いいいいいい
4行目:1列目:No=3
4行目:2列目:日付=2023/03/03
4行目:3列目:追加列=追加C
4行目:4列目:個数=333
4行目:5列目:メモ=うううう
しきい値を示す
もう一つEnumの使い方を紹介します。それは、定数をしきい値として利用する方法です。
以下のEnumは成績の点数によってどのように扱うか、という場合に利用します。
1 2 3 4 5 6 7 8 |
Private Enum 成績値 ランクE = 20 ランクD = 40 ランクC = 60 ランクB = 80 ランクA = 99 ランクS = 100 End Enum |
各定数値には連番ではなく「しきい値」を設定しておきます。
あとは、成績値によって処理を変えたい場合に、Enumで定義した「しきい値の定数」を使ってコーディングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub ランク出力() Dim i As Integer '// 成績値 i = 50 If i <= 成績値.ランクE Then Debug.Print "ランクE:" & i ElseIf i <= 成績値.ランクD Then Debug.Print "ランクD:" & i ElseIf i <= 成績値.ランクC Then Debug.Print "ランクC:" & i ElseIf i <= 成績値.ランクB Then Debug.Print "ランクB:" & i ElseIf i <= 成績値.ランクA Then Debug.Print "ランクA:" & i ElseIf i = 成績値.ランクS Then Debug.Print "ランクS:" & i End If End Sub |
実行結果
ランクC:50
ここでは「ランクC」は41点以上60点以下としていますが、55点以下にしたい場合はEnumの「ランクC」を60から55に書き換えるだけで、本処理は何も手を加える必要がありません。これがEnumでしきい値を使う場合の利点です。