■ 定数と列挙体(列挙型)
プログラムの中で文字や数値のリテラル(値)を使用する場合、値をそのまま記述することを決め打ちと呼びます。決め打ちされたリテラルは、後から管理が大変です。
例えば消費税計算用の数値リテラルを「1.05」で決め打ちしてしまうと、将来消費税率が変更になった場合、該当する箇所の「1.05」を全て変更しなければなりません。
数値リテラルなら、VBEの置き換え機能を使って一括置き換えを行うことも可能でしょうが(あまりお勧めしませんが…)、文字リテラルの場合、表記のゆれによって置き換えしそこなう可能性も考慮に入れる必要があります。
例えば、「出力先プリンター一覧表」と「出力先プリンタ一覧表」のような文字リテラルを、プログラミング内に直接記述することはナンセンスです。
保守のしやすいプログラムでは、必ずこれらのリテラル値をユーザー定数で定義しています。
例えば、先ほどの例ならば、
Public Const CstSyohizei As Long = 1.05
Public Const LstAllPrinter As String = "出力先プリンタ一覧表"
このように定義します。
これならば、消費税やリストの表題を変更する必要が発生した場合、ユーザー定数の定義を変更するだけで、すべての該当箇所に変更を反映させることが可能です。
この他にも、呼び出すファイルのフルパスとか、管理用のパスワード、データベースへの接続文字列など、さまざまな箇所に、ユーザー定数を利用することができます。
例:
Const UserPassword As String = "hoge"
If InputBox("Please Enter User Password") = UserPassword Then
' パスワードが合致した場合の処理
End If
上記の例では、入力された文字列がユーザー定数UserPasswordに合致した場合のみ、Ifブロック内の処理が実行されます。
定数は変数と違い、値を代入することができません。ですので、定数は定義された時点で与えられたリテラル値がプログラム中変更されることなく保持されます。(ユーザーによって書き換えられる心配がありません)
またリテラルをそのまま使用するのに比べて、ユーザー定数は定義された定数名で参照されます。これは、コードの可読性を高め、コード内のマジックナンバー(識別子として用いられる数値リテラル)を減らします。
※なおVBAでは定数配列を定義する(配列の要素を定数として定義する)ことはできません。
※他の定数を参照して定数を定義することができます。その場合は定数の循環参照に注意してください。
例:
Const AdminPassword As String = SuperPassword
Const SuperPassword As String = AdminPassword & "x"
上記の例では、定数がお互いを参照しあっているため循環参照が発生し、コンパイルエラーになります。
列挙体(ユーザー定義列挙型)
ユーザー定数の中には、同じグループの中にまとめることができるものも多く存在します。
例えば、次の定数はグループでひとまとめにしたほうが、より開発・保守がしやすいでしょう。
Public Const BusyoHonsya As Long = 0
Public Const BusyoAomori As Long = 1
Public Const BusyoNagoya As Long = 2
Public Const BusyoOsaka As Long = 3
Public Const BusyoMiyazaki As Long = 4
部署コードをユーザー定数で定義しています。これを、列挙型で定義してみましょう。
Public Enum Busyo
Honsya = 0
Aomori = 1
Nagoya = 2
Osaka = 3
Miyazaki = 4
End Enum
このようになります。
列挙型のすばらしいところは、インテリセンス(自動入力補完機能)が使用できるところです。
Busyo.まで記述したところで、Aomori,Honsya,Miyazaki…と入力候補が表示されるので、目的のメンバをクリックまたはカーソル移動+TABで選択してやればOKです。
列挙型も定数と同じく、値を代入することはできません。
列挙型の値は内部的に長整数型の値として保持されます。ですので、列挙体の各メンバ(列挙定数)に割り当てられる値は整数のみになります。文字列などを割り当てることはできません。
例:
Public Enum Busyo
Honsya = "本社"
…
列挙型のメンバに文字列を定義することはできないのでコンパイルエラーになります。
列挙型はメンバに必ずしも値を定義する必要はありません。値を省略した場合、直前のメンバの値に1増分した値が、全く値を指定しない場合、0を開始値とした整数の連番が値としてセットされます。
例:
Public Enum Busyo
Honsya = 10
Aomori = 20
Nagoya
…
Busyo.Nagoyaには「21」がセットされる。
例:
Public Enum Busyo
Honsya
Aomori
…
Busyo.Honsyaには「0」がBusyo.Aomoriには「1」がセットされる。
列挙型はコンボボックスと併用した使用方法が特に便利です。
CbBusyo.AddItem "本社"
CbBusyo.AddItem "青森"
CbBusyo.AddItem "名古屋"
…
コンボボックスCbBusyoに部署リストを加えます。これらリストのインデックスは0を開始値とした整数の連番で並びますので、次の列挙体に対応します。
Private Enum Busyo
Honsya
Aomori
Nagoya
…
あとは、CbBusyoのリストインデックスを使用して処理を分岐させることができます。
Select Case CbBusyo.ListIndex
Case Busyo.Honsya
' 本社の場合の処理
Case Busyo.Aomori
' 青森の場合の処理
Case Busyo.Nagoya
' 名古屋の場合の処理
…
以上、ユーザー定義列挙型について解説しました。
定数は、コンパイル時に識別子によりチェックされます。また、列挙型は候補の中から選択する形式ですので、基本的に記述ミスをすることはありません。
これらのテクニックは、単にプログラムの可読性を上げるだけでなく、修正に強く、記述ミスをしにくいコードを書くために必須の技術です。
ぜひ、マスターしてあなたのプログラムに応用してください。
最後に、組み込み定数と組み込み列挙型について少し触れます。
VBA,VBには、システムによって提供される組み込み定数や組み込み列挙型が多数存在します。
これらの定数はオブジェクトライブラリに記述されていて、オブジェクトブラウザから参照することが可能です。
※ 組み込み定数・組み込み列挙型と同じ名前のユーザー定義定数・列挙型を作成することはできません。
※ 組み込み定数・組み込み列挙型はオブジェクト、メソッド、プロパティで使用可能です。
※ オブジェクトブラウザはVBEのメニューから表示>オブジェクトブラウザを選択するか、F2キー押下で表示させることができます。
|
|
|