Impedir a digitalização de caracteres que não satisfazem determinadas condições como por exemplo caractere alfa em campos onde o esperado seja números inteiros ou reias é uma dica muito difundida nos meios de comunicação . Talvez para os iniciantes na “languagem” Delphi seja algo novo , a grande maioria sabe que não a é . Nosso objetivo não é massificar a Dica folclórica , e sim tentar acrescentar algo que possa trazer algum beneficio . Parto do princípio da Flexibilidade , da Reutilização e do Reaproveitamento . Falar nesses pilares nos remete a Classe , a Orientação de Objetos , a Padrões de Projeto . Enfim , nos remete a um Delphi que poucos Javanianos conhecem .
Sobre esses Pilares (Flexibilidade , Reutilização , Reaproveitamento) , o Delphi caminhou em passos largos ao incorporar a Regexp (Delphixe) e reformular a Rtti (delphi2010). Novos recuros , novas funcionalidas e a Dica Foclórica ( Key in [‘0’..’9′] ) ja não assusta tanto . Eu particularmente ja a considero decapreted , literalmente virou Foclore.
Vamos a definição de nossa classe que esta definida na uses uKeyPress
unit uKeyPress;
interface
type
TKeyPress = class
public
//Definie qual o conjunto de caracter permitido para o Controle
class Var FPattern:String;
//Método que motificara ou não o Key digitado no controle
class procedure KeyPress(Sender: TObject; var Key:Char);
private
//Método interno que montará um previem do Texto digitado no controle
//esses texto será analizado se é um texto válido ou não
class function Formats_Inputs(sender:Tobject;const key:Char):String;
end;
Segue sua Implementation
Sua Implementation
class function TKeyPress.Formats_Inputs(sender: Tobject;const key:Char): String;
const
Property_Array : Array [0..2] of String = ('Text','SelLength','SelStart');
var
Context:TRttiContext;
Prop:TRttiProperty;
Tipo:TRttiType;
_SelStart:Integer;
_SelLength:integer;
begin
result:=EmptyStr; //inicializa
Tipo:=Context.GetType(Sender.ClassType);
for Prop in Tipo.GetProperties do //varre as propriedades
case AnsiIndexText(Prop.Name,Property_Array) of
0:result:=Prop.GetValue(sender).ToString; //obtem o texto
1:_SelLength:=strtoint(Prop.GetValue(sender).ToString); //obtem a selecao
2:_SelStart:= strtoint(Prop.GetValue(sender).ToString); //obtem a posicao cursor
end;
_SelStart:=_SelStart+_SelLength+1; //posicao de inserçao do carracter key sera a soma
Insert(Key,result,_SelStart); //inseri no texto original o Key digitado na Posicao
end;
class procedure TKeyPress.KeyPress(Sender: TObject; var Key: Char);
var
_Mathes:TMatchCollection;
_Mathe:TMatch;
_Input:String;
_Output:String;
begin
_Input:=TKeyPress.Formats_Inputs(sender,Key);//retorna o texto do Controle inserido o Key
_Mathes:=TRegEx.Matches(_Input,FPattern); //Carrega a colecao seguindo o texto e o Patternn
for _Mathe in _Mathes do //varre a colecao e armazena cada item na variavel output
_Output:=_Output+_Mathe.Value;
if (_Output <> _Input) then //compara se são diferentes
key:=#0; //este caracter não esta permitido segundo o Pattern.
end;
end.
Vamos utilizar esta classe de várias formas diferentes seguindo algumas restrições . Essas restrições podem ser impostas por critérios técnicos na construção do Softaware ou por desejo do Cliente . De modo que temos Flexibilidade nas Regras de Negócio . Vou tentar dar alguns exemplos que acho que pode ser úteis . Alguns triviais ,como por exemplo de só aceitar números inteiros , outros um pouco mais complexos . Segue abaixo alguns Patterns para algumas situações descritas abaixo :
//Uses System.RegularExpressions;
procedure TForm4.Rdg_PatternClick(Sender: TObject);
var
x,y:integer;
begin
y:=SEdt_Y.Value; //È um TSpinEdit;
x:=SEdt_X.Value; //È um TSpinEdit;
Edit1.Clear; //È um TEdit
case Rdg_Pattern.ItemIndex of // Rdg_Pattern é TRadioGroup
//so inteiro
0:TKeyPress.FPattern:='\d*[\b]?';
//Real
1:TKeyPress.FPattern:='^\d+'+
TRegEx.Escape(FormatSettings.DecimalSeparator) +'?\d*[\b]?';
//Real com Duas casas decimais
2:TKeyPress.FPattern:='^\d+'+
TRegEx.Escape(FormatSettings.DecimalSeparator)+'?\d{0,2}[\b]?';
//Real com tres Casas decimais
3:TKeyPress.FPattern:='^\d+'+FormatSettings.DecimalSeparator+'?\d{0,3}[\b]?';
//Real com ate casas 4 Inteiras e 3 casas decimais
4:TKeyPress.FPattern:='^\d{1,4}('+
TRegEx.Escape(FormatSettings.DecimalSeparator)+'\d{0,3})?[\b]?';
//Real com ate Y Casas Inteiras e X Casas Decimais
5:TKeyPress.FPattern:='^\d{1,'+inttostr(Y)+'}('+
TRegEx.Escape(FormatSettings.DecimalSeparator)+'{1}\d{0,'+inttostr(x)+'})?[\b]?';
//Real com ate Y Casas Inteiras e X Casas Decimais precedido deSinal de + ou De -
6:TKeyPress.FPattern:='(^((-|\+)?[\b]?\d{0,'+inttostr(Y)+'}){1}('+
TRegEx.Escape(FormatSettings.DecimalSeparator)+'{1}\d{0,'+inttostr(x)+'})?)[\b]?';
//Procure a acessoria do Professor Mario Guedes
7:TKeyPress.FPattern:='Mario Guedes Resolve';
end;
Edit1.SetFocus;
self.Caption:=TKeyPress.FPattern;
end;
Os mais atentos devem ter notado uma menção singela ao Professor Mario Guedes . na sétima opção do Radio Group. Para aqueles que não conhecem , acredito que a grande maioria da nossa comunidade já teve contato com os artigos do Amigo . Destaco seu pioneirismo tanto em e revista quanto em conferências oficiais da Embarcadero , na orientação de Expressões Regulares . Eu mesmo já me socorri várias vezes de seu conhecimento farto e nada mais justo do que agradecer neste espaço humilde ( não faço música de Fank e nem tenho popozão ) mas não poderia deixar o seu nome e nem o seu blog passar despercebido http://eugostododelphi.blogspot.com.br/
Dando sequência , destaco que esses Patterns não são únicos e nem os melhores para cada situação . Vcs podem obter o mesmo resultado de outras formas e ate mesmo de modo mais eficientes . Esses Patterns são a minha abstração para o problema . Por exemplo , tento não permitir números como o ” ,1233″ onde não existe nada antes da Vírgula . Enfim , testando e adaptando para cada situação .
Para Utilizar a classe é simples
procedure TForm4.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
// TKeyPress.FPattern **** Definido No Oclick do Rdg_PatternClick
//verifica se o caracter digitado é permitido segundo a definicao do Pattern
TKeyPress.KeyPress(Sender,Key);
end;
Caso haja interesse no Exemplo Completo , onde estão as Implementações de todos métodos , Fique a vontade e entre em contato que estarei disponibilizando .
No mais meus agradecimentos pela paciência e leitura e caso alguém necessite
questionar esse trabalho , bem como dúvidas na implementação do exemplo ,utilize à vontade 0 espaço de comentários abaixo. Peço por último , por questões de gentileza e cordialidade , bem como respeito aos direitos autorais , que se alguém quiser acrescentar esta classe em algum veiculo de comunicação , que faça referência a fonte da informação original . Vou ficando por aqui , muito obrigado
Curtir isso:
Curtir Carregando...