VB.NET - Validando CNPJ, CPF


Neste artigo vou mostrar como você pode efetuar a validação e a formatação para CNPJ, CPF usando propriedades de objetos.

O algoritmo de validação não é de minha autoria e estará sendo exibido conforme localizado na web com referência ao seu autor. O código também não é de minha autoria eu apenas localizei na web um código usado para o VB e fiz algumas adaptações trocando as funções de tratamento de string para as mais recentes do VB.NET. Sugiro que antes de utilizar o código em ambiente de produção faça uma verificação meticulosa.

O meu objetivo é mostrar que podemos usar rotinas de propriedades de objetos para validar dados.

Os conceitos teóricos sobre objetos já foram abordados nos artigos a seguir:

Validando CNPJ

O número que compõe o CNPJ é composto por três segmentos de algarismos, sendo o primeiro o número da inscrição propriamente dito, o segundo (após a barra) o número de filiais e o terceiro representados pelos últimos dois valores que são os dígitos verificadores.

Oficialmente o cálculo do número do CNPJ prevê também a verificação do oitavo dígito, mas algumas empresas possuem números que ao serem validados segundo esse critério são considerados inválidos.

Por isso o mais seguro é você fazer a validação dos dígitos verificadores, pois assim nenhum número será inválido e sua rotina está protegida da mesma forma, já que a regra é única e funciona com qualquer CNPJ válido

 

Validando os dígitos verificadores

 

Vamos mostrar o modo de cálculo de modo prático, para isso vamos adotar um número de CNPJ hipotético e calcularemos seus dígitos verificadores: 11.222.333/0001-XX.

Vamos começar alinhando os números que compõe o CNPJ com os algarismos 5,4,3,2,9,8,7,6,5,4,3 e 2 nesta ordem, veja:

1 1 2 2 2 3 3 3 0 0 0 1
5 4 3 2 9 8 7 6 5 4 3 2

Feito isso efetuaremos a multiplicação de cada uma das colunas, assim:

1 1 2 2 2 3 3 3 0 0 0 1
5 4 3 2 9 8 7 6 5 4 3 2
5 4 6 4 18 24 21 18 0 0 0 2

Com os valores encontrados em cada uma das colunas efetuaremos o somatório, desta forma: 5+4+6+4+18+24+21+18+0+0+0+2 e com o número obtido, nesse caso 102, realizaremos a divisão por 11 (102/11).

Vamos considerar como quociente somente o valor inteiro, o resto da divisão será responsável pelo cálculo do primeiro dígito verificador. Assim sendo, no nosso caso o resto da divisão é o número 3.

Neste momento temos a seguinte regra: Caso o resto da divisão seja menor que 2 o valor do dígito verificador passa a ser 0, caso contrário subtraímos o valor de 11 para obter o dígito, que é o nosso caso, portanto nosso primeiro dígito verificador é (11 - 3) o número 8.

Para seguirmos com a nossa validação tomaremos o CNPJ com o primeiro dígito já calculado para efetuarmos a validação do segundo e último dígito verificador: 11.222.333/0001-8X.

O processo é semelhante a primeira etapa, a única mudança é a seqüência de números que serão alinhados na tabela, como a tabela ficou maior com a presença do dígito já calculado a seqüência agora tem que ter mais um número e ficará assim: 6,5,4,3,2,9,8,7,6,5,4,3 e 2, confira:

1 1 2 2 2 3 3 3 0 0 0 1 8
6 5 4 3 2 9 8 7 6 5 4 3 2
6 5 8 6 4 27 24 21 0 0 0 3 16

 Como você pode notar efetuamos também, como na primeira etapa, a multiplicação das colunas e faremos agora o somatório das resultados obtidos: 6+5+8+6+4+27+24+21+0+0+0+3+16. Com o resultado obtido, nesse caso 120, efetuamos a divisão por 11.

Nessa divisão, assim como no cálculo anterior, vamos apenas considerar o valor inteiro do quociente, pois o cálculo do último dígito verificador será feito com o resto da divisão seguindo a seguinte regra: caso o resto da divisão seja menor que 2 (dois), esse valor passa automaticamente a ser zero; caso contrário, que é o nosso caso, subtrai-se o resto de 11 para obter o valor do último dígito verificador, acompanhe: 120/11=10 com resto 10, 11-10 dígito verificador 1 - Nosso CNPJ agora completo 11.222.333/0001-81

Plínio Cruz (Analista de Sistemas / Consultor em Informática)

O que é DV módulo 11 e o que é DV módulo 10 ?

DV (Dígito de Verificação), também denominado número-controle, são dígitos incorporados a números para possibilitar a detecção de erros de digitação, no ato. Recurso muito difundido, por exemplo, na numeração de contas de depósitos bancários.

No caso do CNPJ, o DV módulo 11 corresponde ao resto da divisão por 11 do somatório da multiplicação de cada algarismo da base respectivamente por 9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6 e 5, a partir da unidade. O resto 10 é considerado 0 (algumas instituições, como o Banco do Brasil, tratam o 10, em seus números de contas, como "X").

O DV módulo 10 corresponde ao número que faltar para inteirar múltiplo de 10, em relação ao somatório da multiplicação de cada algarismo da base respectivamente por 2, 1, 2, 1, 2, 1 e 2, a partir da unidade, sendo que em cada multiplicação valores superiores a 9 deverão sofrer a operação "noves fora".

Veja, abaixo, exemplo de cálculo de DV módulo 11 (o mais usado pelos bancos) e de DV módulo 10 para o CNPJ nº 18781203/0001:

1  8  7  8  1  2  0  3  0  0  0  1 = 2               
x  x  x  x  x  x  x  x  x  x  x  x               
6  7  8  9  2  3  4  5  6  7  8  9            
----------------------------------                 
6+56+56+72+ 2+ 6+ 0+15+ 0+ 0+ 0+ 9 = 222÷11=20, com resto 2

1  8  7  8  1  2  0  3  0  0  0  1  2 = 8
x  x  x  x  x  x  x  x  x  x  x  x  x
5  6  7  8  9  2  3  4  5  6  7  8  9
-------------------------------------
5+48+49+64+ 9+ 4+ 0+12+ 0+ 0+ 0+ 8+18 = 217÷11=19, com resto 8

Portanto, CNPJ+DV = 18781203/0001-28

-----------------------------------------------------

Conferência do oitavo dígito:

1  8  7  8  1  2  0  =  3
x  x  x  x  x  x  x
2  1  2  1  2  1  2
-------------------
2+ 8+ 5*+8+ 2+ 2 +0 = 27, para 30 = 3 (*noves fora)

Criando a classe para validação de CNPJ e CPF

Como eu já disse o meu objetivo é mostrar como podemos usar propriedades de objetos para efetuar validação. Vamos criar a classe com suas propriedades e métodos e depois mostrar como podemos usá-la para efetuar a validação de CNPJ e CPF.

Comece criando um novo projeto do VB.NET do tipo Windows Application usando a linguagem VB.NET.

No menu Project selecione a opção Add Class e informe o nome  valida_CNPJ_CPF.vb clicando a seguir no botão Open.

A primeira coisa que vamos fazer é definir as propriedades da classe definindo as seguintes variáveis :

Private dadosArray() As String = {"111.111.111-11", "222.222.222-22", "333.333.333-33", "444.444.444-44", _
                                              "555.555.555-55", "666.666.666-66", "777.777.777-77", "888.888.888-88", "999.999.999-99"}

Private Const msgErro As String = "Dados Inválidos"
Private bValida As Boolean
Private sCPF As String
Private sCNPJ As String

Criarei agora a propriedade cpf(). Com esta propriedade estaremos permitindo a definição de um valor para o CPF e a obtenção do valor do cpf atribuído. Note que se o cpf for inválido estamos lançando uma exceção. Poderíamos também ter atribuído um outro valor ao membro sCPF e feito o tratamento posteriormente.

Public Property cpf() As String

Get

     Return sCPF

End Get

Set(ByVal Valor As String)

    bValida = ValidaCPF(Valor)

    If bValida Then

        sCPF = Valor

    Else

       Throw (New System.ArgumentException(msgErro, "Numero do CPF"))

    End If

End Set

End Property

A outra propriedade que criamos chama-se isCpfValido() que retorna True/False e usa o método ValidaCPF(cpf) passando como parâmetro o valor atribuído a propriedade cpf. Note que esta propriedade é somente leitura (ReadOnly), ou seja, só podemos obter valores através dela e não atribuir.

Public ReadOnly Property isCpfValido() As Boolean

Get

    bValida = ValidaCPF(cpf)

   If bValida Then

       Return True

    Else

      Return False

    End If

End Get

End Property

Da mesma forma vou criar duas propriedades para o CNPJ: cnpj() e isCnpjValido(cnpj), cujo código exibo a seguir:

Public Property cnpj() As String
        Get
            Return sCNPJ
        End Get
        Set(ByVal Valor As String)
            bValida = ValidaCNPJ(Valor)
            If bValida Then
                sCNPJ = Valor
            Else
                Throw (New System.ArgumentException(msgErro, "Numero do CNPJ"))
            End If
        End Set
    End Property
 
    Public ReadOnly Property isCnpjValido() As Boolean
        Get
            bValida = ValidaCNPJ(cnpj)
            If bValida Then
                Return True
            Else
                Return False
            End If
        End Get
    End Property

 

Falta exibir o código dos método da classe que fazem a validação do CPF e CNPJ.

A função ValidaCPF() possui o seguinte código:

Private Function ValidaCPF(ByVal CPF As String) As Boolean

        Dim i, x, n1, n2 As Integer

        CPF = CPF.Trim
        For i = 0 To dadosArray.Length - 1
            If CPF.Length <> 14 Or dadosArray(i).Equals(CPF) Then
                Return False
            End If
        Next
        'remove a maskara
        CPF = CPF.Substring(0, 3) + CPF.Substring(4, 3) + CPF.Substring(8, 3) + CPF.Substring(12)
        For x = 0 To 1
            n1 = 0
            For i = 0 To 8 + x
                n1 = n1 + Val(CPF.Substring(i, 1)) * (10 + x - i)
            Next
            n2 = 11 - (n1 - (Int(n1 / 11) * 11))
            If n2 = 10 Or n2 = 11 Then n2 = 0

            If n2 <> Val(CPF.Substring(9 + x, 1)) Then
                Return False
            End If
        Next

        Return True
    End Function

O método ValidaCNPJ() e o método efetivaValidação() são exibidos a seguir:

 Private Function ValidaCNPJ(ByVal CNPJ As String) As Boolean

        Dim i As Integer
        Dim valida As Boolean
        CNPJ = CNPJ.Trim

        For i = 0 To dadosArray.Length - 1
            If CNPJ.Length <> 18 Or dadosArray(i).Equals(CNPJ) Then
                Return False
            End If
        Next

        'remove a maskara
        CNPJ = CNPJ.Substring(0, 2) + CNPJ.Substring(3, 3) + CNPJ.Substring(7, 3) + CNPJ.Substring(11, 4) + CNPJ.Substring(16)
        valida = efetivaValidacao(CNPJ)

        If valida Then
            ValidaCNPJ = True
        Else
            ValidaCNPJ = False
        End If

    End Function

    Private Function efetivaValidacao(ByVal cnpj As String)
        Dim Numero(13) As Integer
        Dim soma As Integer
        Dim i As Integer
        Dim valida As Boolean
        Dim resultado1 As Integer
        Dim resultado2 As Integer
        For i = 0 To Numero.Length - 1
            Numero(i) = CInt(cnpj.Substring(i, 1))
        Next
        soma = Numero(0) * 5 + Numero(1) * 4 + Numero(2) * 3 + Numero(3) * 2 + Numero(4) * 9 + Numero(5) * 8 + Numero(6) * 7 + _
                   Numero(7) * 6 + Numero(8) * 5 + Numero(9) * 4 + Numero(10) * 3 + Numero(11) * 2
        soma = soma - (11 * (Int(soma / 11)))
        If soma = 0 Or soma = 1 Then
            resultado1 = 0
        Else
            resultado1 = 11 - soma
        End If

        If resultado1 = Numero(12) Then
          soma = Numero(0) * 6 + Numero(1) * 5 + Numero(2) * 4 + Numero(3) * 3 + Numero(4) * 2 + Numero(5) * 9 + Numero(6) * 8 + _
                       Numero(7) * 7 + Numero(8) * 6 + Numero(9) * 5 + Numero(10) * 4 + Numero(11) * 3 + Numero(12) * 2
            soma = soma - (11 * (Int(soma / 11)))
            If soma = 0 Or soma = 1 Then
                resultado2 = 0
            Else
                resultado2 = 11 - soma
            End If
            If resultado2 = Numero(13) Then
                Return True
            Else
                Return False
            End If
        Else
            Return False
        End If

    End Function

Efetuando a validação dos dados

Acione o menu Project e selecione Add Windows Form e Inclua um formulário no projeto; neste formulário inclua os controles : TextBox e Button conforme abaixo:

Para efetuar validação do CPF inclua no evento Click do botão - Valida CPF - o seguinte código:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


Dim cpf1 As New valida_CNPJ_CPF


cpf1.cpf = TextBox1.Text


If
cpf1.isCpfValido() Then

    MsgBox("CPF valido")

Else

    MsgBox("CPF Inválido")

End If

End Sub

- Dim cpf1 As New valida_CNPJ_CPF - cria uma instância da classe valida_CNPJ_CPF

- cpf1.cpf = TextBox1.Text  - atribui a propriedade cpf o valor do cpf informado no campo de texto TextBox1.text.

- O código abaixo usa a propriedade isCpfValido() , que chama o método ValidaCPF(cpf), para verificar se o CPF informado é válido.

If cpf1.isCpfValido() Then

    MsgBox("CPF valido")

Else

    MsgBox("CPF Inválido")

End If

O mesmo procedimento é feito para a validação do CNPJ.

Formatando os dados no formulário para CPF e CNPJ

É de boa prática efetuar a formatação dos dados no formulário para facilitar a vida do usuário e para permitir que os dados sejam enviados de forma correta.

A seguir vou mostrar como você pode formatar a informação do CPF e do CNPJ em uma caixa de texto - TextBox.

Formatando o CPF

A formatação do CPF usa a seguinte máscara:  999.999.999-99

Podemos efetuar a formatação usando o controle MaskEditBox conforme já mostrei no artigo: VB.NET - Usando o controle Mask Edit.

Mas vou mostrar uma outra maneira de fazer isto usando apenas código VB.NET. Abaixo temos o código que efetua a formatação do CPF:

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) 
Handles TextBox1.KeyPress

        If IsNumeric(e.KeyChar) AndAlso TextBox1.TextLength < TextBox1.MaxLength Then
            TextBox1.Text &= e.KeyChar
            TextBox1.SelectionStart = TextBox1.TextLength
            Call formatacpf(TextBox1)
        End If
        e.Handled = True

    End Sub
    Private Sub formatacpf(ByVal txtTexto As Object)
        If Len(txtTexto.Text) = 3 Then
            txtTexto.Text = txtTexto.Text & "."
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        ElseIf Len(txtTexto.Text) = 7 Then
            txtTexto.Text = txtTexto.Text & "."
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        ElseIf Len(txtTexto.Text) = 11 Then
            txtTexto.Text = txtTexto.Text & "-"
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        End If
    End Sub

No evento KeyPress da caixa de texto o código mostrado somente permite valores numéricos sendo que a quantidade de digitos permitida não deve ser superior a informada na propriedade MaxLength do controle, que no caso é igual a 14.

Conforme o usuário digita a rotina formatacpf() é chamada e nela usando a propriedade SelectionStart vamos inserindo a máscara nas posições 3,7 e 11.

Para exigir que algum valor seja informado estou usando o evento Validating da caixa de texto para verificar se foi informado algum valor, e, também estou obrigando que o valor informado tenha que ter o tamanho definido em MaxLength.(14).

Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating


If Me.TextBox1.Text = String.Empty OrElse Me.TextBox1.Text.Length <> TextBox1.MaxLength Then

     MsgBox("Informe um valor válido para CPF.(Formato: 999.999.999-99", MsgBoxStyle.Critical)

     e.Cancel = True

End If
 

End Sub

Se você usar o evento Validating como foi feito acima, se tentar sair do formulário sem informar algum valor na caixa de texto irá receber a mensagem de erro. Para contornar isto sobrescrevemos o método OnClosing() conforme abaixo para permitir que isto seja possível.

'sobrescrevendo o meto OnClosing permite sair do formulário sem preencher os campos texto

Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)

    e.Cancel = False

End Sub

Formatando o CNPJ

A formatação do CNPJ usa a seguinte máscara:  99.999.999/9999-99

O código para formatação do CNPJ é dado a seguir,  sendo que o funcionamento é idêntico ao que já foi explicado acima:

Private Sub TextBox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
 Handles TextBox2.KeyPress

        If IsNumeric(e.KeyChar) AndAlso TextBox2.TextLength < TextBox2.MaxLength Then
            TextBox2.Text &= e.KeyChar
            TextBox2.SelectionStart = TextBox2.TextLength
            Call formatacnpj(TextBox2)
        End If
        e.Handled = True
    End Sub
 
    Private Sub formatacnpj(ByVal txtTexto As Object)
        If Len(txtTexto.Text) = 2 Or Len(txtTexto.Text) = 6 Then
            txtTexto.Text = txtTexto.Text & "."
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        End If

        If Len(txtTexto.Text) = 10 Then
            txtTexto.Text = txtTexto.Text & "/"
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        End If
        If Len(txtTexto.Text) = 15 Then
            txtTexto.Text = txtTexto.Text & "-"
            txtTexto.SelectionStart = Len(txtTexto.Text) + 1
        End If
    End Sub

 

Executando o projeto teremos como resultado final o seguinte:

Pegue o código do projeto aqui : ValidaCPFCNPJ.zip

Até o próximo artigo VB.NET ...


José Carlos Macoratti