case文を使用すると、条件文を読みやすい形で記述できますが、
ご存知のように文字列型を式に使用することはできません。
そこでcase文で利用できる型を使いつつ要素を名前で指定する方法を考えてみましょう。
TypeInfo関数は、型識別子に対してコンパイラが生成した実行時型情報へのポインタを返します。
GetEnumValue関数は、指定した文字列表現の列挙型の値を返します。
(それぞれ、uses節に「System.TypInfo」を追加すると使用可能)
この2つの関数を組み合わせて使用することで、
文字列を列挙型に変換してcase文で利用できるようにしています。
次のコードでは、英語の曜日名をEdit1に入力し、
ボタンをクリックしたときに表示するメッセージを変えるようにしています。
uses
System.TypInfo; // TypeInfoやGetEnumValueを使用するために必要
type
TDayNameE = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
procedure TForm1.Button1Click(Sender: TObject);
var
DayName : TDayNameE;
begin
DayName := TDayNameE(GetEnumValue(TypeInfo(TDayNameE), Edit1.Text));
// Edit1の値が一致するか判定する(※大文字小文字の区別なし)
case DayName of
Sunday, Saturday : ShowMessage('休日');
Monday..Friday : ShowMessage('平日');
else
ShowMessage('???'); // 一致する要素が無かった場合
end;
end;
typeで列挙型を扱う場合、古いバージョンでは日本語を使用できませんでした。
(新しい11や10.2等では変数名や列挙型の要素名に日本語を使用できますが、
お客様によっては開発規約等で避けるよう規定されている場合もあるかと存じます。)
//(列挙型で日本語を扱う例)
type
TDayNameJ = (日, 月, 火, 水, 木, 金, 土);
日本語を使用できない場合には、
次のような関数を作成し、日本語の値をその順序を表す整数に変換することが可能です。
(ここでは「GetDayName」という関数で作成)
function GetDayName(ADayName: String): Integer;
const
DayNameStr: array [0..6] of String = ('日','月','火','水','木','金','土');
var
i: Integer;
begin
Result := -1;
for i := Low(DayNameStr) to High(DayNameStr) do
if DayNameStr[i] = ADayName then
begin
Result := i;
Break;
end;
end;
上記のGetDayName関数を利用し曜日名をEdit1に日本語で入力し、
ボタンをクリックしたときに表示するメッセージを変えるようにするには次のように記述します。
procedure TForm1.Button2Click(Sender: TObject);
begin
case GetDayName(Edit1.Text) of
0, 6 : ShowMessage('休日');
1..5 : ShowMessage('平日');
else
ShowMessage('???');
end;
end;
関数の戻り値は変数のため、ケースリストとして使用できません。
次の例のような記述を行った場合、変数となるため
「定数式が必要です」コンパイルエラーとなりますのでご注意ください。
// 使用できない例
case GetDayName(Edit1.Text) of
GetDayName('日'), GetDayName('土') : ShowMessage('休日');
GetDayName('月')..GetDayName('金') : ShowMessage('平日');
else
ShowMessage('???');
end;
(ミガロ.情報マガジン「MIGARO News!!」Vol.068 2006年9月号より)