VBAのEnumの「メンバーの名前」をデータとして取得する方法
VBAには列挙型Enumという数値を定義するものがあります。プログラム中で整数値で「3」などと数字をそのまま使うと何のことかわからなくなったりしますし、後で修正するときにもとても不都合です。Enumはそういうのを避けるために、何かの番号とかをあらかじめ名前に割り当てて定義しておきます。
こんな感じです。
Private Enum testE
No = 0
Name
Address
Item
End Enum
こうすると、testE.Noは実行時に0が割り当てられます。testE.Nameなら1です。
通常は、こうやって使えばそれでよいだけなのですが、どうしても、どうしても、このEnumの定義文字そのものをプログラム中で欲しいという時があります。でも普通は、VBAではそれはできません。(C#だとできます。)
普通はできないし、しないのですが、VBEを操作するVBProjectというオブジェクトにVBAのソースコードそのものを取得する仕組みがありますので、それを使って簡単なコードを書けば可能になります。
今、以下のような列挙型の定義があるとします。
Private Enum testEnum
'アジア
Japan = 5
'北米
Americ = 7
'ヨーロッパ
England = 10
France 'フランス
Spain 'スペイン
'南米
Brasil = 20
Chili
End Enum
作成したコードを使うと
Japan 5
Americ 7
England 10
France 11
Spain 12
Brasil 20
Chili 21
という文字列と数値が取得できます。
取得のためのソースコードは以下です。詳しい説明は省きます。よくわからないままにやるとひどい目に合う(VBA作成中にExcelがフリーズしたり、再起動して作成したものが消えてしまう)ことがあるので、VBEを操作する内容のほかの人のWEB記事を、あらかじめお調べください。すいません。
Public Sub testGetEnumMember()
Const ModName = "Module1" '取得するモジュールの名前
Const WordS = "Private Enum testEnum" '対象のEnumの開始文字
Const WordE = "End Enum" '対象のEnumの終了文字
Dim member As Dictionary
Set member = GetEnumMember(ModName, WordS, WordE)
'結果の表示。
Dim keywd As Variant
For Each keywd In member.Keys
Debug.Print keywd, member(keywd)
Next
End Sub
Private Function GetEnumMember(ModName As String, WordS As String, WordE As String) As Dictionary
'参照設定で
'「Microsoft Visual Basic for Applications Extensibility 5.3」
'を追加した方が良い。
'宣言部分を取得
Dim VBCs As VBComponents 'VBコンポーネンツ。VBA全体のオブジェクト
Set VBCs = ThisWorkbook.VBProject.VBComponents
Dim VBC As VBComponent 'VBコンポーネント。標準モジュールなどのオブジェクト
Set VBC = VBCs(ModName)
Dim CM As CodeModule 'コードモジュール。ソースコードのオブジェクト
Set CM = VBC.CodeModule
Dim decline As Long
decline = CM.CountOfDeclarationLines 'グローバル宣言部の行数。
Dim buff As Variant
buff = Split(CM.Lines(1, decline), vbCrLf) 'グローバル宣言部を取得して、行に分割
Set CM = Nothing
Set VBC = Nothing
Set VBCs = Nothing
Dim member As New Dictionary 'Enumのメンバーを保存する辞書
Dim cnt As Long 'Enumの値
cnt = 0
Dim flg As Boolean '必要範囲になったことを示すスイッチ
flg = False
Dim pos As Long 'コメント除去、値取得時に使う文字数カウント
Dim str As String, preEQ As String, postEQ As String 'コメント除去、値取得時に使う文字変数
Dim i As Long
For i = 0 To UBound(buff) '宣言部を1行ずつ調べる
str = buff(i)
'終了かチェックする
If flg And InStr(1, str, WordE) > 0 Then
Exit For
End If
'対象のEnumの行
If flg Then
preEQ = ""
postEQ = ""
'コメント除去
pos = InStr(1, str, "'")
If pos > 0 Then
str = Left(str, pos - 1)
End If
If Trim(str) <> "" Then '空行は飛ばす
'値取得
pos = InStr(1, str, "=")
If pos > 0 Then
preEQ = Trim(Left(str, pos - 1))
postEQ = Mid(str, pos + 1)
cnt = CLng(postEQ)
Else
preEQ = Trim(str)
cnt = cnt + 1
End If
'辞書に登録
member(preEQ) = cnt
End If
End If
'対象のEnumに入ったかチェックする
If InStr(1, str, WordS) > 0 Then
flg = True
End If
Next
Set GetEnumMember = member
Set member = Nothing
End Function
#Excel ,#VBA,#VBE, #VBComponents ,#CodeModule
いいなと思ったら応援しよう!
応援してやろうということで、お気持ちをいただければ嬉しいです。もっと勉強したり、調べたりする糧にしたいと思います。