17/04/2010

CPF e CNPJ na mesma rotina

Não querendo ser repetitivo, mas já sendo. Vou apresentar uma rotina para calcular o CPF e CNPJ. Só que desta vez tudo em uma coisa só.

Eu não gosto de rotinas extensas muito menos redundantes. Mesmo já tendo ouvido falar que uma rotina mais extensa se torna mais fácil dar manutenção, ainda prefiro olhar varias vezes para um pouquinho de linhas e tentar achar onde está Wally do que ficar rolando a barra de scroll, ou ainda ficar quicando de uma sub-rotina a outra. Então procuro fazer uso dos recursos disponíveis e fazer o menor e mais eficiente código possível.

Nessa rotina de verificação eu organizei as seqüências de cálculos para serem executadas de uma só vez e de modo a calcular tanto o CPF quanto CNPJ.

A primeira atitude tomada por ela é extrair apenas os números do CNP, eliminando qualquer outro tipo de caractere. Em seguida verifica se todos os números são iguais, caso positivo já encerra ali mesmo.

Pela quantidade dos dígitos limpos saberemos se é um CPF ou um CNPJ, assim uma array é carregada com a sequência de valores de calculo para cada tipo, e logo em seguida executa-se o cálculo.

O retorno é verdadeiro ou falso.


Dim Nm(),Mt() As Integer 
Dim i,n As Integer 'Contadores
Dim Dv1, Dv2 As Integer 'Digitos de verificação
Dim chek As Boolean = True 'Controle
Dim vResto As Double 'Resultado
Dim s() As String

s = CNP.Split("") 'Separar todos os caracteres

For i = 0 to s.Ubound 'Deixar apenas numeros
if IsNumeric(s(i)) Then Nm.Append s(i).val
Next

For i = 0 To Nm.Ubound - 2 //numeros iguais: "222.222.222.22"
if Nm(i) = Nm(i + 1) Then n = n + 1
Next
if n = Nm.Ubound - 1 Then Return False 'Sair se todos os numeros forem iguais

Select case Nm.Ubound //Pelo tamanho, sabemos se é um cpf ou cnpj
Case 10 // CNPF "0 a 10 = 11"
Mt = Array(11, 10, 9, 8, 7, 6, 5, 4, 3, 2)
Case 13 // CNPJ "0 a 13 = 14"
Mt = Array(6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2)
Case Else
Return False 'NUMERO NAO É CALCULAVEL
end select

//Primeiro caltulo nos digitos
For i = 0 To Mt.Ubound -1
Dv1 = Dv1 + (Nm(i) * Mt(i + 1))
Dv2 = Dv2 + (Nm(i) * Mt(i))
Next

//Calcular dígito 1
vResto = Dv1 Mod 11
chek = vResto > 1
Dv1 = (11 - vResto) * Abs(Bin(chek).val)

//Calcular digito 2
vResto = (Dv2 + (Dv1 * 2)) Mod 11
chek = (vResto > 1)
Dv2 = (11 - vResto) * Abs(Bin(chek).val)

Return (Nm(Nm.Ubound-1) = Dv1) AND (Nm(Nm.Ubound) = Dv2)

10/04/2010

MySql e Ultimo ID

MySql e Ultimo ID = titulo de filme do velho oeste :)

Em outros tempos e em outras linguagens eu travava a tabelas, inseria e re-consultava.

Mas aqui e agora...

Quando você executar uma instrução INSERT e precisar do ID que esta instrução gerou para qualquer outra coisa é só perguntar para a conexão do MySql.

id = MyCnn.GetInsertID //MyCnn = conexão com banco de dados misql

Você também pode perguntar quantos registros foram afetados por uma instrução com GetAffectedRows (por ex: quantos registros eu deletei?)