VBAのメッセージボックスでは、以下のように適用したいスタイルを足し算できる。
Sub hoge() MsgBox "処理を続行しますか。", vbYesNo + vbQuestion + vbDefaultButton2, "確認" End Sub
上記のマクロを実行すると、このように表示される。
変な文法だと思われた方もいるだろう。
MsgBoxは関数である。ふつう関数に引数を複数渡そうと思ったら、ひとつずつカンマ区切りで渡す。
ただ上の例では「vbYesNo + vbQuestion + vbDefaultButton2」と足し算している。
今回はこれの仕組みを解説しようと思う。
MsgBoxでオプションを足し算できる仕組み
まず、それぞれの定数の値をイミディエイトウインドウで確認してみると、4、32、256と出る。
全て足し合わせると、292だ。では292を直接渡してみよう。
Sub hoge() MsgBox "処理を続行しますか。", 292, "確認" End Sub
これでも同じ表示になる。
実はMsgBoxに指定できる定数値は以下のようになっており、これらを一つずつ組み合わせて292を作ろうと思ったら、必然的に「256=vbDefaultButton2」、「32=vbQuestion」、「4=vbYesNo」の組み合わせになるのだ。
定数 | 値 |
vbApplicationModal | 0 |
vbDefaultButton1 | 0 |
vbOKOnly | 0 |
vbOKCancel | 1 |
vbAbortRetryIgnore | 2 |
vbYesNoCancel | 3 |
vbYesNo | 4 |
vbRetryCancel | 5 |
vbCritical | 16 |
vbQuestion | 32 |
vbExclamation | 48 |
vbInformation | 64 |
vbDefaultButton2 | 256 |
vbDefaultButton3 | 512 |
vbDefaultButton4 | 768 |
vbSystemModal | 4096 |
vbMsgBoxHelpButton | 16384 |
vbMsgBoxSetForeground | 65536 |
vbMsgBoxRight | 524288 |
vbMsgBoxRtlReading | 1048576 |
つまり足し合わせて渡しても、定数表をもとに分解できるということ。
定数値を1、2、4、8、16と倍々にしていくと、それらの組み合わせは元の定数に分解できるのだ。
※一部48や768などの2のn乗になっていないものがあるが、これは32+16、512+256の組み合わせになっている。2進数を学習すると意味が分かると思うのでここでは説明を割愛。
ただし、同じカテゴリのプロパティを足し合わせるとおかしなことになる。
たとえば以下のようにすると、32+16だから、48=vbExclamationと同じことになる。
Sub hoge() MsgBox "Hello", vbQuestion + vbCritical End Sub
こうすると、
Sub hoge() MsgBox "Hello", vbYesNo + vbYesNo + vbYesNo + vbYesNo End Sub
こうなる。
4+4+4+4=16=vbCriticalなので。
自分で同じ仕組みを作って理解する。
さて、では列挙型を使用して自分で同じ仕組みを作ってみよう。
今回は人物の特徴を題材にコードを書いてみた。
まずはEnumで列挙型定数を宣言する。
Enum 人物の特徴 男性 = 1 女性 = 2 裸眼 = 4 コンタクト = 8 メガネ = 16 スリム = 32 ふくよか = 64 A型 = 128 B型 = 256 AB型 = A型 + B型 O型 = 512 End Enum
そして、人物の特徴を表示させるためのプロシージャを用意。
Sub 表示(T As 人物の特徴) Dim 血液型 As String If T >= O型 Then 血液型 = "O型" T = T - O型 ElseIf T >= AB型 Then 血液型 = "AB型" T = T - AB型 ElseIf T >= B型 Then 血液型 = "B型" T = T - B型 Else 血液型 = "不明" End If Dim 体型 As String If T >= ふくよか Then 体型 = "ふくよか" T = T - ふくよか ElseIf T >= スリム Then 体型 = "スリム" T = T - スリム Else 体型 = "標準" End If Dim 視力矯正 As String If T >= メガネ Then 視力矯正 = "メガネ" T = T - メガネ ElseIf T >= コンタクト Then 視力矯正 = "コンタクト" T = T - コンタクト ElseIf T >= 裸眼 Then 視力矯正 = "裸眼" T = T - 裸眼 Else 視力矯正 = "不明" End If Dim 性別 As String If T >= 女性 Then 性別 = "女性" T = T - 女性 ElseIf T >= 男性 Then 性別 = "男性" T = T - 男性 End If MsgBox "この人物の特徴" & vbNewLine _ & "性別:" & 性別 & vbNewLine _ & "視力矯正:" & 視力矯正 & vbNewLine _ & "体型:" & 体型 & vbNewLine _ & "血液型:" & 血液型 End Sub
このプロシージャでは人物の特徴を大きな値のものから探し、見つかったらその値を引く。残った数値からまた大きな値を探して引くという繰り返しでデータを分解していく。
では実際に呼び出してみよう。
Sub Main() 表示 メガネ + 男性 + ふくよか + AB型 End Sub
実行すると、足し合わせて渡した値が正しく表示されているのがわかる。
このように合計値を数値で渡しても同じ結果になる。
Sub Main() 表示 465 End Sub
以上がメッセージボックスのオプションが足し算できる仕組みである。
もしこの仕組みをより詳しく知りたければ、今回私が書いたコードをそのままVBEで手入力してみると良い。入力候補が適切に表示され、VBエディタが定数の計算をよくアシストしてくれるのがわかる。