最初に、私の英語についてお詫び申し上げます。今私の問題に。
TypInfo.GetEnumName() を使用して Variantのコンテンツタイプの文字列表現を取得するにはどうすればよいですか。私は次のことを試しましたが、運が悪いと数値表現が得られます。
myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );
ありがとうございました。
最初に、私の英語についてお詫び申し上げます。今私の問題に。
TypInfo.GetEnumName() を使用して Variantのコンテンツタイプの文字列表現を取得するにはどうすればよいですか。私は次のことを試しましたが、運が悪いと数値表現が得られます。
myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );
ありがとうございました。
Variant型の文字列表現を取得するには、組み込みのDelphi関数を使用するだけです。
var
MyVariantType: string;
MyVariant: Variant;
begin
MyVariant := 'Hello World';
MyVariantType := VarTypeAsText(VarType(MyVariant));
ShowMessage(MyVariantType); //displays: String
MyVariant := 2;
MyVariantType := VarTypeAsText(VarType(MyVariant));
ShowMessage(MyVariantType); //displays: Byte
end;
Delphi 2007 ヘルプからの引用:
GetEnumName を使用して、Delphi 列挙値をコード内で表す記号名に変換します。
つまり、TVarData.VType は列挙値ではなく、Windows SDK の wtypes.h ファイルから取得した System.pas の定数の 1 つに設定された整数であるため、その目的には使用できません。GetEnumName()のソースを見ると、整数の値を含む文字列がすぐに返されます。
編集:
TVarData.VType の文字列表現を取得する他の方法はありますか
文字列表現は手動で決定できます。最初に、その整数にはいくつかのビットの情報がエンコードされていることに注意する必要があります。そのため、単純な case ステートメントまたは配列ルックアップは機能しません。下位 12 ビットは型マスクであり、上位ビットは、それがベクトル型か配列型か、および参照によって与えられるかどうかに関する情報をエンコードします。重要な部分は次のとおりです。
const
varTypeMask = $0FFF;
varArray = $2000;
varByRef = $4000;
したがって、次のようなことができます。
function VariantTypeName(const AValue: TVarData): string;
begin
case AValue.VType and varTypeMask of
vtInteger: Result := 'integer';
// ...
end;
if AValue.VType and varArray <> 0 then
Result := 'array of ' + Result;
if AValue.VType and varByRef <> 0 then
Result := Result + ' by ref';
end;
これは列挙型ではないため、手動で行う必要があります。次のように書きます。
function VariantTypeName(const value: TVarData): string;
begin
case value.VType of
vtInteger: result := 'integer';
//and so on
end;
または、System.pas の値が順番にリストされているため、文字列の const 配列を宣言して、VariantTypeName 関数が配列の適切なメンバーを返すようにすることもできます。
VarTypeAsText をサポートしていないバージョンの Delphi については、次のように考えています。 VType 値に続く列挙型を自分で定義できます。
type
{$TYPEINFO ON}
TMyVarType = (
varEmpty = System.varEmpty,
varNull = System.varNull,
// etc...
);
(未使用の列挙型スロットも埋めます。この理由については、列挙型で「type has no typeinfo」エラーが発生する理由を参照してください)。
次に、これらの関数を使用して、バリアントの型を独自の列挙型として読み取ります。
function MyVarType(VType: TVarType): TMyVarType; overload;
begin
Result := TMyVarType(VType);
end;
function MyVarType(V: Variant): TMyVarType; overload;
begin
Result := TMyVarType(TVarData(V).VType);
end;
そして、次のように文字列に変換できます。
function VarTypeToString(aValue: TMyVarType): string;
begin
Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;