I аm trying to get the enumeration name value using RTTI.
My objective is to get the corresponding enumerate name value in Enum1(Tsex) from the selected enumerate name value in Enum2(iterator) using a string value.
Here is the code that I have implemented. I am using Delphi 7.
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs,typinfo;
type
Tsex = (homme,femme);
iterator = (H,F);
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
var
i : integer;
OT: Tsex;
FT: iterator;
begin
i:=0;
OT := Low(Tsex);
for FT := Low(iterator) to High(iterator) do
if GetEnumName(TypeInfo(iterator), Ord(FT)) = 'F' then
begin
showmessage(GetEnumName(TypeInfo(Tsex), Ord(OT)));
end;
i:=i+1;
OT:=Succ(OT);
end;
When I use H
as a string I get homme
, but when I use F
I also get homme
. But it needs to be femme
.
The problem in your code is that you are missing a begin
after for
, and this causes increment of i
and assignment of OT
to happen after the iteration is complete.
What you need to change is:
var
i : integer;
OT: Tsex;
FT: iterator;
begin
i:=0;
OT := Low(Tsex);
for FT := Low(iterator) to High(iterator) do
begin // <- Add begin here
if GetEnumName(TypeInfo(iterator), Ord(FT)) = 'F' then
begin
showmessage(GetEnumName(TypeInfo(Tsex), Ord(OT)));
end;
i:=i+1;
OT:=Succ(OT);
end;
end; // <- Add end; here
As David has pointed out, it is better to use an array to map another set of values to your enum. Like this:
type
TSex = (homme, femme);
const
SexDBValues: array [TSex] of string =
('H', 'F');
type
TForm1 = class(TForm)
procedure FormShow(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetMyEnumValue(const aDBValue: string): TSex;
var
value: TSex;
begin
for value := Low(TSex) to High(TSex) do
begin
if SameText(SexDBValues[value], aDBValue) then
begin
Result := value;
Exit;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
var
value: TSex;
begin
value := GetMyEnumValue('H');
ShowMessage(GetEnumName(TypeInfo(TSex), Ord(value)));
end;
And when your enum type contains only two values, and is unlikely to have additional values in future, you can just use good old if-else operator:
function GetMyEnumValue(const aDBValue: string): TSex;
begin
if SameText(aDBValue, 'F') then
begin
Result := femme;
end else
begin
Result := homme;
end;
end;
In few words, avoid overengineering problems.
Note: We are using string
to store the character value and SameText
to compare it, as it compares text case-insensitively. Plus, it allows you to compare text of multiple characters, if in future you change your mind on how values are stored in DB.
I would also recommend you to consult with Delphi Coding Style Guide.
It might seem unrelated to problem, but following good practice on indentation helps to avoid such problems.
Guidelines on naming types and variables are also important. They will similarly save you in other situations.