Pergunta

Em primeiro lugar, desculpas para o meu Inglês, eu espero que isso faz sentido que I`ve escrito aqui. Agora para o meu problema.

Como posso obter a representação de string do conteúdo tipo de um Variant usando TypInfo.GetEnumName (). Eu tentei o seguinte, sem sorte, eu recebo uma representação numérica.

myString := GetEnumName( TypeInfo(TVarType), TVarData(myVar).VType );

Obrigado.

Foi útil?

Solução

Basta usar o build-in função de Delphi para obter a representação de cadeia de um tipo Variant.

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;

Outras dicas

Citando a ajuda Delphi 2007:

Use GetEnumName para converter um valor enumerado Delphi para o nome simbólico que representa-lo no código.

Isso significa que você não pode usá-lo para essa finalidade, como TVarData.VType não é um valor enumerado, mas um número inteiro que é definido para uma das constantes em system.pas que são tirada do Windows SDK wtypes.h arquivo. Olhada na fonte de GetEnumName () , ele não retornou imediatamente uma string contendo o valor do inteiro.

Editar:

Existe alguma outra maneira de obter a representação de cadeia de TVarData.VType

Você pode determinar a representação de cadeia manualmente. Primeiro você precisa estar ciente de que existem vários bits de informação codificada em que inteiro, assim que uma simples declaração caso ou matriz de pesquisa não vai funcionar. Os 12 bits mais baixos são o tipo de máscara, e a informação bits de codificação superior sobre se se trata de um tipo de vector ou matriz e se ele é dado por referência ou não. As partes importantes são:

const
  varTypeMask = $0FFF;
  varArray    = $2000;
  varByRef    = $4000;

Então, você poderia fazer algo como:

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;

Uma vez que não é uma enumeração, você terá que fazê-lo manualmente. Escrever algo como isto:

function VariantTypeName(const value: TVarData): string;
begin
  case value.VType of
    vtInteger: result := 'integer';
    //and so on
end;

Ou, já que os valores em system.pas estão listados em ordem, você pode tentar declarar uma matriz const de cordas e ter a sua função VariantTypeName devolver o membro apropriado da matriz.

Aqui está um pensamento para versões do Delphi que não suportam VarTypeAsText: Você poderia definir um tipo de enumerate-se que segue os valores vtype:

type
  {$TYPEINFO ON}
  TMyVarType = (
    varEmpty = System.varEmpty, 
    varNull = System.varNull,
    // etc...
    );

(Preencher os slots não utilizados enum também - veja por que recebo "tipo não tem typeinfo" erro com um tipo enum para o raciocínio por trás disso).

Em seguida, usar essas funções para ler o tipo Variantes, como seu próprio tipo de enumerate:

function MyVarType(VType: TVarType): TMyVarType; overload;
begin
  Result := TMyVarType(VType);
end;

function MyVarType(V: Variant): TMyVarType; overload;
begin
  Result := TMyVarType(TVarData(V).VType);
end;

E então você pode convertê-lo para uma string como esta:

function VarTypeToString(aValue: TMyVarType): string;
begin
  Result := GetEnumName(TypeInfo(TMyVarType), Ord(aValue));
end;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top