ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Retornar o opção do enum a partir do nome do tipo e da opção
Ir à página 1, 2  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Seg Nov 06, 2017 9:42 am    Assunto: Retornar o opção do enum a partir do nome do tipo e da opção Responder com Citação

Tenho o nome do tipo de um enum e a opção, todos em String. Como obter o tipo equivalente?

Exemplo:

Código:
type
  TFruta = (tfAbacate, tfBanana, tfCaju);

var
  Tipo, Valor: String;
  Fruta: TFruta;
begin
  Tipo := 'TFruta';
  Valor := 'tfBanana';

  Fruta := funcaoAqui(Tipo, Valor);
end;

_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Nov 06, 2017 11:09 am    Assunto: Responder com Citação

Não sei se vai ser o suficiente para te ajudar, mas criei uma função usando a unit TypInfo.

Pode ser melhorada, pois não consegui converter o parâmetro Tipo (string) para TFruta.

Função:

Código:
function getFruta(valor: string): TFruta;
begin
  Result := TFruta(GetEnumValue(TypeInfo(TFruta), valor));
end;


Exemplo de uso:

Código:
var
  Fruta: TFruta;
begin
  Fruta := getFruta('tfBanana');
end;


Neste link tem outra maneira:
https://stackoverflow.com/questions/2472487/converting-an-string-to-a-enum-type-using-tvalue
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Seg Nov 06, 2017 11:13 am    Assunto: Re: Retornar o opção do enum a partir do nome do tipo e da opção Responder com Citação

marcieldeg escreveu:
Tenho o nome do tipo de um enum e a opção, todos em String. Como obter o tipo equivalente?

Exemplo:

Código:
type
  TFruta = (tfAbacate, tfBanana, tfCaju);

var
  Tipo, Valor: String;
  Fruta: TFruta;
begin
  Tipo := 'TFruta';
  Valor := 'tfBanana';

  Fruta := funcaoAqui(Tipo, Valor);
end;


normalmente faço desta forma aqui:
Código:
type
  TFruta = (tfAbacate, tfBanana, tfCaju);

function FrutaToString(value:TFruta):string; // retorna o nome do enumerador, acredito que com o uso da RTTI é possível buscar este valor
begin
  result:='Desconhecido';
  case value of
    tfAbacate:result:='tfAbacate';
    tfBanana:result:='tfBanana';
    tfCaju:result:='tfCaju';
  end;
end;

function StingToFruta(value:string):TFruta; // retorna o tipo do enumerador, aqui não há mesmo outra forma, nem mesmo com o RTTI, acredito eu, posso estar enganado
begin
if uppercase(value)=uppercase('tfAbacate') then result:=tfAbacate;
if uppercase(value)=uppercase('tfBanana') then result:=tfBanana;
if uppercase(value)=uppercase('tfCaju') then result:=tfCaju;
end;

var
  Tipo, Valor: String;
  Fruta: TFruta;
begin
  Tipo := 'TFruta'; // Fruta ja seria um TFruta, logo bastaria de uma função que informasse apenas o nome do enumerador, a menos claro que estivesse a querer fazer typecast de outros types para Tfruta havendo claro uma equivalência, para isso ambos types deveria ser nomeados e enumerados.
  Valor := 'tfBanana';

  Fruta := StingToFruta(Valor);
end;




a menos claro que estivesse a querer fazer typecast de outros types para Tfruta havendo claro uma equivalência, para isso ambos types deveria ser nomeados e enumerados.
Para caso de types diferente e com equivalências

Código:
type
  TFruta = (tfAbacate=1, tfBanana=2, tfCaju=3);
  TColorPen = (tfPreto=1, tfBranco=2, tfAzul=3);



neste caso é possivel fazer typecas dos dois tipos

Código:
var
fruta1:TFruta;
pen1:TColorPen;
begin
pen1:=tfBranco;
fruta:=TFruta(integer(pen1));// cá é possível o type cast logo seria possivel criar uma função do tipo mencionada acima por vc  funcaoAqui(Tipo, Valor);
end;


não sei bem se ha a nescessidade de realizar um typecast para integer primeiro, sei que seria funcional desta forma, mais como ambos são enumerados é possivel que funcionasse apenas como TFruta(pen1);
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Seg Nov 06, 2017 12:01 pm    Assunto: Responder com Citação

natanbh1 escreveu:
Não sei se vai ser o suficiente para te ajudar, mas criei uma função usando a unit TypInfo.

Pode ser melhorada, pois não consegui converter o parâmetro Tipo (string) para TFruta.

Função:

Código:
function getFruta(valor: string): TFruta;
begin
  Result := TFruta(GetEnumValue(TypeInfo(TFruta), valor));
end;


Exemplo de uso:

Código:
var
  Fruta: TFruta;
begin
  Fruta := getFruta('tfBanana');
end;


Neste link tem outra maneira:
https://stackoverflow.com/questions/2472487/converting-an-string-to-a-enum-type-using-tvalue


Preciso obter pelo nome do tipo do enum em String, pois é o retorno de um webservice.

Código:
<TFruta>tfBanana</TFruta>


mas pode ser outro enum:

Código:
<TAnimal>tmAvestruz</TAnimal>

ou "qualquer outra coisa".

Claro que não é "qualquer", os enums possívels estão em uma unit compartilhada pelos dois projetos (da aplicação cliente e do webservice). Mas há uma lista bem grande de enums.
_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Seg Nov 06, 2017 12:07 pm    Assunto: Responder com Citação

Cheguei a criar uma classe wrapper da TypInfo para retornar o enum pelo nome, mas com ela preciso do tipo do enum, ou seja, não me atende. Vou deixar a dica aqui caso alguém initeresse:


Código:

type
  TEnumUtils<T> = class
    class function FromName(AName: String): T;
  end;

class function TEnumUtils<T>.FromName(AName: String): T;
begin
  PInteger(@Result)^ := GetEnumValue(TypeInfo(T), AName);
end;


Uso:

Código:
fruta := TEnumUtils<TFruta>.FromName('tfBanana');


O objetivo é conseguir uma função tipo

Código:
function ValueFromEnumName(AEnumType, AEnumName: String): Integer;


Que me retorna o valor ordinal de qualquer enum.
_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Seg Nov 06, 2017 12:11 pm    Assunto: Responder com Citação

Neste caso como se trata de uma retorno de webservice eu recomendaria o uso de uma extrutura record tipo

Código:
Type

  Tretorno=record
    Tipo:string; // poderá vim do webservice qualquer tipo
    Valor:string; // poderá vim do webservice qualquer valor
  end;


O porque disso? Se eu tratar ele como um tipo enumerador eu estarei limitando minha aplicação a trabalhar apenas com os tipos previamente editado no código fonte de minha aplicação, e caso num futuro próximo este webservice introduza novos tipos e ou mude seus tipo minha aplicação toda vai apresentar erros não tratáveis, forçando-me a introduzir no codigo fonte os novos tipos ou as alteração e uma nova recompilação.

Sendo um record posso eu posso ir cadastrando os tipos e seus valores em uma tabela a medidas que os dados estão chegando sem qualquer problema futuros.
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Seg Nov 06, 2017 12:30 pm    Assunto: Responder com Citação

strak2012 escreveu:
Neste caso como se trata de uma retorno de webservice eu recomendaria o uso de uma extrutura record tipo

Código:
Type

  Tretorno=record
    Tipo:string; // poderá vim do webservice qualquer tipo
    Valor:string; // poderá vim do webservice qualquer valor
  end;


O porque disso? Se eu tratar ele como um tipo enumerador eu estarei limitando minha aplicação a trabalhar apenas com os tipos previamente editado no código fonte de minha aplicação, e caso num futuro próximo este webservice introduza novos tipos e ou mude seus tipo minha aplicação toda vai apresentar erros não tratáveis, forçando-me a introduzir no codigo fonte os novos tipos ou as alteração e uma nova recompilação.

Sendo um record posso eu posso ir cadastrando os tipos e seus valores em uma tabela a medidas que os dados estão chegando sem qualquer problema futuros.


A sua sugestão não resolve o problema inicial, mas obrigado pela dica.
_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Seg Nov 06, 2017 11:19 pm    Assunto: Responder com Citação

Veja se desta forma te atende, se é que entendi o que você deseja:



Código:
type
    TOrdem = (fPrimeiro, fSegundo, fTerceiro);

procedure TForm1.Button1Click(Sender: TObject);
var
   I: Byte;
begin
     ComboBox1.Items.Clear;
     for I := Ord(Low(Ordem)) to Ord(High(Ordem)) do
         ComboBox1.Items.Add(GetEnumName(TypeInfo(TOrdem), I));
end;






bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Ter Nov 07, 2017 8:13 am    Assunto: Responder com Citação

johnny-walker escreveu:
Veja se desta forma te atende, se é que entendi o que você deseja:



Código:
type
    TOrdem = (fPrimeiro, fSegundo, fTerceiro);

procedure TForm1.Button1Click(Sender: TObject);
var
   I: Byte;
begin
     ComboBox1.Items.Clear;
     for I := Ord(Low(Ordem)) to Ord(High(Ordem)) do
         ComboBox1.Items.Add(GetEnumName(TypeInfo(TOrdem), I));
end;






bye


Não é isso.

Usando seu exemplo
Código:
type
    TOrdem = (fPrimeiro, fSegundo, fTerceiro);


Preciso de uma função que receba os argumentos como string.

Código:
valor := funcao('TOrdem', 'fPrimeiro'); // valor deve receber 0


Os parâmetros obrigatoriamente são em String.

Talvez seja possível somente pelo nome do enum:
Código:
valor := funcao('fPrimeiro'); // valor deve receber 0

Já que no Delphi não posso ter 2 enumeradores com as mesmas opções.
_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Ter Nov 07, 2017 8:41 am    Assunto: Responder com Citação

O 'X' da questão no seu caso é conseguir fazer este 'Cast' de String para o 'Nome' do tipo enumerado.

O conversão que vi foi do valor. Tanto de String para algum valor do tipo enumerado quanto vice-versa.

Nas pesquisas que fiz não vi nada neste sentido, não sei se é possível.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Ter Nov 07, 2017 12:45 pm    Assunto: Responder com Citação

Eis aí, tente desta forma:

Código:
type
  TEnumTest = (Primeriom, Segundo, Terceiro, Quarto, Quinto, Sexto, Setimo);

function StrToEnumTest(aStr:String):TEnumTest;
begin
  result := TEnumTest(GetEnumValue(TypeInfo(TEnumTest) ,aStr));
end;

function EnumTestToStr(EnumTest: TEnumTest): string;
begin
 Result := GetEnumName(TypeInfo(TEnumTest), Integer(EnumTest));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   FSet: TEnumTest;
begin
     FSet:= StrToEnumTest('Setimo');
     ShowMessage(EnumTestToStr(FSet));
end;


Este utiliza generics:
https://stackoverflow.com/questions/2472487/converting-an-string-to-a-enum-type-using-tvalue

bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Ter Nov 07, 2017 1:11 pm    Assunto: Responder com Citação

marcieldeg escreveu:

Preciso de uma função que receba os argumentos como string.

Código:
valor := funcao('TOrdem', 'fPrimeiro'); // valor deve receber 0


Os parâmetros obrigatoriamente são em String.

_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Ter Nov 07, 2017 1:15 pm    Assunto: Responder com Citação

Estou tentando usar o método TRttiContext.FindType(), mas retorna null para enums.

Código:
function GetTypeInfoFromName(ATypeName: String): pTypeInfo;
var
  C: TRttiContext;
  T: TRttiType;
begin
  T := TRttiContext.Create.FindType(ATypeName);
  if not Assigned(T) then
    raise Exception.CreateFmt('Type %s not found', [ATypeName]);

  result := T.Handle;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetTypeInfoFromName('Unit1.TOrdem'); // retorna null
  GetTypeInfoFromName('Unit1.TForm1'); // retorna certo
end;


Se conseguir obter o TRttiType do enum, consigo recuperar os valores do enum.
_________________
"Olha a interface da IDE! Será que ela é? Será que ela é? DELPHI!"
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Ter Nov 07, 2017 1:43 pm    Assunto: Responder com Citação

Você já viu este link, talvez te ajude:


https://drgarcia1986.wordpress.com/2012/11/12/conhecendo-um-pouco-da-rtti-parte-ii/


bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Ter Nov 07, 2017 1:45 pm    Assunto: Responder com Citação

estive a olhar a extrutura do TypeInfo e até consegui pegar o nome do enumerador e seu valor

Código:
PTypeInfo(TypeInfo(TFruta)).Name // retorna o nome 'TFruta'
PTypeInfo(TypeInfo(TFruta)).TypeData.NameList // retorna o valor 'tfAbacate'
PTypeInfo(TypeInfo(TFruta)).Kind // reconhece que o type é um tkEnumeration


Estou tentando usar estas informações em conjunto com o que foi postado pelo johnny-walker para ver se consigo confeccionar a função
Código:
function toType(tipo,valor:string) :pointer;


O problema estar é pegar o type pelo nome para fazer um cast, e isso não me vem nada na cabeça a não ser arranjar uma forma de listar todos os types na aplicação para ir comparando com o argumento que foi inserido.

talvez mais alguém pode dá uma luz.
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Ir à página 1, 2  Próximo
Página 1 de 2

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB