Enum(列挙体)の裏技【VBA】
皆さんEnum(列挙体)使っていますか?
Long型の定数をまとめて定義できるアレです。基本的な使い方は私が紹介するまでもないと思うので、知らない方はググってください。
今回はググってもあんまり出てこなさそうな、けれども知っていると便利かもしれない技を紹介します。
プロシージャの仮引数に設定してインテリセンス(入力補完)が使える
前に呟いたことがあるので載せます。
私はよく使うのですが意外と知られていない気がします。
例示すると、
— reime (@_reime) April 24, 2019
Enum eColumn
eNo = 1
eName
End Enum
Function EnumTest(col As eColumn)
(処理)
End Function
みたく仮引数に列挙型(col As eColumn)を設定する。
すると別のプロシージャで、
EnumTest(
まで書くとeNoとeName『だけが』候補として入力補完に表示されるのだ。
普通の定数ではなくEnumを使う利点の1つはインテリセンス(入力補完)だと思いますが、プロシージャの仮引数にEnum型の変数を定義することで呼び出すときにもインテリセンスを利用できます。
EnumとFunctionを定義して、
呼び出してやると、
みたく使えます。
使いどころですが、選択肢が決まっていて引数で分岐させたい場面(例えばデータベースの接続先を指定するとか)で威力を発揮します。
あとこのテクニックはSelect Case文と、とても相性が良いです。EnumはLong型しか定義できない為、Select Case文で文字列などに変換してやります。
難点があるとすれば仮引数のEnum変数にPrivateを設定した場合、他のプロシージャから呼べないという点でしょうか。
Private Enumであってもちゃんとインテリセンスが効くのでいけるかと思いきや、
コンパイルエラーになります。
なのでEnumを引数に設定するときはPublic(既定値)にして、多用するときはバッティングしないような命名にしましょう。
メンバを非表示に出来る
これもあんまり見たことない気がします。
VBEでF2キーを押すとオブジェクトブラウザが開き、オブジェクトとそのメンバの一覧が表示されますが、実はここに表示されず、インテリセンスにも出てこない隠れたメンバが存在します。
有名どころで言えば、Rangeオブジェクトのデフォルトプロパティである_Defaultプロパティ(※よく勘違いされているけれどもValueプロパティではない)でしょうか。
Range("a1").まで入力しても_Defaultは出てきません。
先頭にアンダースコア(「_」のこと。アンダーバーとも)が付いているメンバーは通常非表示になっています。
しかしオブジェクトブラウザの任意の場所で右クリックをして「非表示のメンバーを表示」にチェックをすると、
この通り、隠れたメンバが表示されます。これが非表示メンバです。
さてこの非表示メンバですが、自作のクラスやプロシージャには実装できません。
しかし、なぜかEnum(列挙体)だけはできます。
↑の[_eLast]みたいに先頭にアンダースコアを付けて括弧で括ることで、
ちゃんと非表示になります。
(応用)Enumの要素数を(条件付きで)取得できる
Enumの特性として、要素の値を省略すると直前のメンバ + 1 (先頭のメンバは0)の値が割り振られます。
言葉にすると難しいですが、要するに連番になります(↑の画像の右も左も同じ値が入ります)。
勘の良い方はお気づきかと思いますが、この[_eLast]の値を取得できればEnumの要素数を算出できます。
たとえば、こんな関数を書くとか。
ポイントは[_eLast]が非表示メンバなので、インテリセンスには表示されず、コーディング時のノイズにならない点です。
項目が増える際には[_eLast]の直前に追加します。
おわりに
Enumってよくシートの値を配列とかに格納する際に、列番号がマジックナンバーになるのを避ける目的で使われると思います。
ただまぁ、列ってよく増減するんですよね。そんなときにEnumの要素数を算出できるとコードの修正が少なくて済むので便利だよなーって考えていました。