Nesse artigo explico como validar e formatar campo CPF e CNPJ.  Nesse artigo vamos  usar  o  evento  OnExit do Edit  mas  também  poderia  ser  de  um DBEdit.  O grande  barato  dessa  forma  de trabalhar é que a formatação não fica presa no Edit, aparecendo  para o cliente uma formatação  de pontos, traços, etc. Essa formatação parte após a verificação de tamanho e se o campo passou na validação.

Vamos lá, crie um novo projeto (File/New/VCL Forms Application – Delphi.

Coloque no Formulário um Label e Dois Edits. Como imagem abaixo:

 

Coloque no Caption do Label CPF / CNPJ, iremos manipular também esse Label fazendo ele receber um valor de CPF ou CNPJ de acordo com o dado digitado.

Coloquei dois Edits pelo fato de ter que tabular, para que o evento OnExit seja disparado, mas só usaremos o primeiro.

Criaremos duas funções, uma para validar CPF e outra para validar CNPJ. Para quem não sabe a diferença entre functions e procedures vai a explicação a procedure não retorna nenhum valor, ou seja ela executa sem retorno, já a function possui um retorno. No nosso caso, um resultado boolean (True ou False).

Declare estas duas functions na sessão private do Form.

  private

         { Private declarations }

         function cnpj(num: string): boolean;

         function cpf(num: string): boolean; // Ctrl+shift+c <= aqui

   public

        { Public declarations }

  end;

Tecle CTRL + SHIFT + C ao lado da declaração da function CPF para que o Delphi crie a função. Assim deve ficar sua função CNPJ:

function TForm1.cnpj(num: string): boolean;

var

   n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12: integer;

   d1,d2: integer;

   digitado, calculado: string;

begin

   n1:=StrToInt(num[1]);

   n2:=StrToInt(num[2]);

   n3:=StrToInt(num[3]);

   n4:=StrToInt(num[4]);

   n5:=StrToInt(num[5]);

   n6:=StrToInt(num[6]);

   n7:=StrToInt(num[7]);

   n8:=StrToInt(num[8]);

   n9:=StrToInt(num[9]);

   n10:=StrToInt(num[10]);

   n11:=StrToInt(num[11]);

   n12:=StrToInt(num[12]);

   d1:=n12*2+n11*3+n10*4+n9*5+n8*6+n7*7+n6*8+n5*9+n4*2+n3*3+n2*4+n1*5;

   d1:=11-(d1 mod 11);

   if d1>=10 then d1:=0;

     d2:=d1*2+n12*3+n11*4+n10*5+n9*6+n8*7+n7*8+n6*9+n5*2+n4*3+n3*4+n2*5+n1*6;

     d2:=11-(d2 mod 11);

   if d2>=10 then d2:=0;

     calculado:=inttostr(d1)+inttostr(d2);

     digitado:=num[13]+num[14];

   if calculado=digitado then

     cnpj:=true

   else

     cnpj:=false;

end;

E assim sua função CPF:

function TForm1.cpf(num: string): boolean;

var

   n1,n2,n3,n4,n5,n6,n7,n8,n9: integer;

   d1,d2: integer;

   digitado, calculado: string;

begin

   n1:=StrToInt(num[1]);

   n2:=StrToInt(num[2]);

   n3:=StrToInt(num[3]);

   n4:=StrToInt(num[4]);

   n5:=StrToInt(num[5]);

   n6:=StrToInt(num[6]);

   n7:=StrToInt(num[7]);

   n8:=StrToInt(num[8]);

   n9:=StrToInt(num[9]);

   d1:=n9*2+n8*3+n7*4+n6*5+n5*6+n4*7+n3*8+n2*9+n1*10;

   d1:=11-(d1 mod 11);

   if d1>=10 then d1:=0;

     d2:=d1*2+n9*3+n8*4+n7*5+n6*6+n5*7+n4*8+n3*9+n2*10+n1*11;

     d2:=11-(d2 mod 11);

   if d2>=10 then d2:=0;

     calculado:=inttostr(d1)+inttostr(d2);

     digitado:=num[10]+num[11];

   if calculado=digitado then

     cpf:=true

   else

     cpf:=false;

end;

 

Agora no evento OnExit do Edit1 coloque o seguinte código:


procedure TForm1.Edit1Exit(Sender: TObject);

Var

   FormatarCNPJ:String;

   FormatarCPF:String;

begin

   if Length(Edit1.Text) <> 0 then

     if Length(Edit1.Text) = 14 then

       Begin

         if cnpj(Edit1.Text) = True Then

         Begin

            FormatarCNPJ:= Copy(Edit1.Text, 1,2)

            + '.' + Copy(Edit1.Text, 3,3)

            +'.' + Copy(Edit1.Text, 6,3)

            + '/' +Copy(Edit1.Text, 9,4)

            + '-' + Copy(Edit1.Text, 13,2);

            Edit1.Text:= FormatarCNPJ;

            Label1.Caption := 'CNPJ';

         End

         Else

         begin

            ShowMessage('CNPJ com erro. favor verificar');

            Edit1.SetFocus;

         end;

      End

      Else

      if Length(Edit1.Text) = 11 then

      Begin

         if cpf(Edit1.Text) = True Then

         Begin

            FormatarCPF:= Copy(Edit1.Text, 1,3)

            + '.' + Copy(Edit1.Text, 4,3)

            + '.' + Copy(Edit1.Text,7,3)

            + '-' + Copy(Edit1.Text, 10,2);

            Edit1.Text:= FormatarCPF;

            Label1.Caption := 'CPF';

         End

         Else

         begin

             ShowMessage('CPF com erro. favor verificar');

             Edit1.SetFocus;

         end;

       End

       Else

       Begin

           ShowMessage ('O CPF tem 11 nº e CNPJ tem 14 nº.'#13'Prencha com números');

           Edit1.SetFocus;

           Edit1.SelectAll;

       End;

end;


Se você compilar o Projeto nesse momento, funcionaria perfeitamente. Porem se voltar no Edit1 e tabular, ele vai dar erro, por causa da formatação. Uma forma de acertar este erro é colocar no evento OnEnter o seguinte código: 


procedure TForm1.Edit1Enter(Sender: TObject);

var

    I: integer;

    S, Texto: string;

begin

    S := '';

    Texto := Edit1.Text;

    for I := 1 to Length(Texto) do

    begin

        if (Texto[I] in ['0'..'9']) then

        begin

            S := S + Copy(Texto, I, 1);

        end;

    end;

    Edit1.Text := S;

end;


            Este código tem a função de toda vez que entrar no Edit, retirar qualquer caracter  que não seja numérico.


Compile o projeto e faça os testes,


Espero ter ajudado,

Abraço.


Marco A. S. Carvalho

marco@cestecnologia.com.br