| Exibir mensagem anterior :: Exibir próxima mensagem | 
	
	
		| Autor | Mensagem | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 9:42 am    Assunto: Retornar o opção do enum a partir do nome do tipo e da opçã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 |  | 
	
		|  | 
	
		| natanbh1 Colaborador
 
  
 
 Registrado: Terça-Feira, 15 de Março de 2011
 Mensagens: 3093
 Localização: Belo Horizonte - MG
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 11:09 am    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| strak2012 Colaborador
 
  
  
 Registrado: Segunda-Feira, 13 de Janeiro de 2014
 Mensagens: 1518
 Localização: Maceió - AL
 
 | 
			
				|  Enviada: 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 |   |  
				| 
 |  
				|  	  | 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 12:01 pm    Assunto: |   |  
				| 
 |  
				|  	  | 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 12:07 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| strak2012 Colaborador
 
  
  
 Registrado: Segunda-Feira, 13 de Janeiro de 2014
 Mensagens: 1518
 Localização: Maceió - AL
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 12:11 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 12:30 pm    Assunto: |   |  
				| 
 |  
				|  	  | 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 |  | 
	
		|  | 
	
		| johnny-walker Moderador
 
  
  
 Registrado: Sábado, 4 de Outubro de 2003
 Mensagens: 10653
 Localização: Contagem/MG - BRAZIL
 
 | 
			
				|  Enviada: Seg Nov 06, 2017 11:19 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 8:13 am    Assunto: |   |  
				| 
 |  
				|  	  | 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 |  | 
	
		|  | 
	
		| natanbh1 Colaborador
 
  
 
 Registrado: Terça-Feira, 15 de Março de 2011
 Mensagens: 3093
 Localização: Belo Horizonte - MG
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 8:41 am    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| johnny-walker Moderador
 
  
  
 Registrado: Sábado, 4 de Outubro de 2003
 Mensagens: 10653
 Localização: Contagem/MG - BRAZIL
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 12:45 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 1:11 pm    Assunto: |   |  
				| 
 |  
				|  	  | 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 |  | 
	
		|  | 
	
		| marcieldeg Colaborador
 
  
  
 Registrado: Terça-Feira, 5 de Abril de 2011
 Mensagens: 1054
 Localização: Vitória - ES
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 1:15 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		| johnny-walker Moderador
 
  
  
 Registrado: Sábado, 4 de Outubro de 2003
 Mensagens: 10653
 Localização: Contagem/MG - BRAZIL
 
 |  | 
	
		| Voltar ao Topo |  | 
	
		|  | 
	
		| strak2012 Colaborador
 
  
  
 Registrado: Segunda-Feira, 13 de Janeiro de 2014
 Mensagens: 1518
 Localização: Maceió - AL
 
 | 
			
				|  Enviada: Ter Nov 07, 2017 1:45 pm    Assunto: |   |  
				| 
 |  
				| 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 |  | 
	
		|  | 
	
		|  |