Resulta muy habitual en
programación la verificación del NIF y CIF en prácticamente todas las
aplicaciones que manejan clientes o proveedores de cualquier tipo. Resulta
absurdo programar una y otra vez las mismas funciones. En programación
orientada a objetos lo lógico es implementar estas funciones en un pequeño
módulo de utilidades o en una clase y utilizarlas desde el código de cliente
una y otra vez sin tener la necesidad de estar tocándolas o reprogramándolas
constantemente, a no ser que cambie la legislación o el método de cálculo. Cosa
que si sucediera bastaría con adaptar estas funciones y no habría que rastrear
otra vez todo el código de los programas
para cambiarlo de nuevo, esa es la verdadera potencia de la programación
orientada a objetos.
Imports
System.Text
Module
Funciones_Basicas
'Calcula la letra del NIF a partir de sus Números
Private Function CalculaNIF(ByVal strA As String) As String
Const
cCADENA As String
= "TRWAGMYFPDXBNJZSQVHLCKE"
Const
cNUMEROS As String
= "0123456789"
Dim a,
b, c, NIF As Integer
Dim sb As New StringBuilder
strA = Trim(strA)
If
Len(strA) = 0 Then Return
""
' Dejar sólo
los números
For i As Integer = 0 To strA.Length - 1
If
cNUMEROS.IndexOf(strA(i)) > -1 Then
sb.Append(strA(i))
End
If
Next
strA = sb.ToString
a = 0
NIF = CInt(Val(strA))
Do
b = CInt(Int(NIF
/ 24))
c = NIF - (24 * b)
a = a + c
NIF = b
Loop While b <> 0
b = CInt(Int(a
/ 23))
c = a - (23 * b)
Return
strA & Mid(cCADENA, CInt(c + 1), 1)
End Function
Aprovechando
la función anterior podemos crear otras dos funciónes, la primera verifica un
CIF y la segunda un NIF.
'Verifica si un CIF introducido es correcto, devuelve true
si es correcto y false en caso contrario
Public Function
Verificar_CIF(ByVal valor As String) As Boolean
Dim
strLetra As String,
strNumero As String,
strDigit As String
Dim
strDigitAux As String
Dim
auxNum As Integer
Dim i As Integer
Dim
suma As Integer
Dim
letras As String
letras = "ABCDEFGHKLMPQSX"
valor
= UCase(valor)
If Len(valor) < 9 OrElse
Not IsNumeric(Mid(valor, 2, 7)) Then
Return False
End If
strLetra = Mid(valor, 1, 1) ' letra del CIF
strNumero = Mid(valor, 2, 7) ' Código de Control
strDigit = Mid(valor, 9) ' CIF menos primera y última posición
If InStr(letras, strLetra) = 0 Then ' comprobamos la letra
del CIF (1ª posición)
Return False
End If
For i =
1 To 7
If
i Mod 2 = 0 Then
suma = suma + CInt(Mid(strNumero, i, 1))
Else
auxNum = CInt(Mid(strNumero, i, 1)) * 2
suma = suma + (auxNum \ 10) + (auxNum Mod 10)
End If
Next
suma = (10 - (suma Mod 10)) Mod 10
Select Case strLetra
Case
"K", "P",
"Q", "S"
suma = suma + 64
strDigitAux = Chr(suma)
Case "X"
strDigitAux =
Mid(CalculaNIF(strNumero), 8, 1)
Case Else
strDigitAux = CStr(suma)
End Select
If
strDigit = strDigitAux Then
Return
True
Else
Return
False
End If
End Function
Esta
función verifica la validez de un NIF
'Verifica si un NIF introducido es correcto, devuelve true
si es correcto y false en caso contrario
Public Function
Verificar_NIF(ByVal valor As String) As Boolean
Dim aux As String
valor
= valor.ToUpper ' ponemos la letra en mayúscula
aux =
valor.Substring(0, valor.Length - 1) ' quitamos la
letra del NIF
If aux.Length >= 7 AndAlso
IsNumeric(aux) Then
aux = CalculaNIF(aux) '
calculamos la letra del NIF para comparar con la que tenemos
Else
Return
False
End If
If
valor <> aux Then ' comparamos las letras
Return
False
End If
Return True
End Function
End Module
Creadas estas
tres funciones podemos hacer uso de ellas desde el código cliente, por ejemplo
podemos definir una clase CDatosGenericos que verifique los
datos introducidos, la clase también incluye las porpiedades para introducir l
datos genéricos como el nombre, dirección. Y un pequeño método que verifique
que un código postal tiene 5 posiciones.
Public
Class CDatosGenericos
Private
m_cif_nif As String
Private m_nombre
As String
Private
m_direccion As String
Private
m_ciudad As String
Private
m_cp As String
Private
m_provincia As String
Private
m_observaciones As String
Private m_activo As Boolean
'Esp es true si el NIF/CIF es español, en ese caso valida
la letra, si esp es False permite cualquier formato.
'Persona_Fisica es True si es un NIF (fisico), false si es
CIF (Juridico), indiferente si Esp es False
Public Property CIF_NIF(ByVal Esp As Boolean, ByVal
Persona_Fisica As Boolean)
As String
Get
Return
m_cif_nif
End Get
Set(ByVal Value As String)
If
Esp = True Then
If
Persona_Fisica = True Then
'Aqui valida la letra
del NIF
If Verificar_NIF(Value) = True Then
m_cif_nif = Value
Else
MsgBox("El NIF es incorrecto")
End If
Else
'Aqui valida la letra del CIF
If Verificar_CIF(Value) = True Then
m_cif_nif = Value
Else
MsgBox("El CIF es incorrecto")
End If
End If
Else
'SI no es español no lo verifica
m_cif_nif = Value
End
If
End Set
End Property
Public Property Nombre() As String
Get
Return
m_nombre
End Get
Set(ByVal Value As String)
m_nombre = Value
End Set
End Property
Public Property Direccion() As
String
Get
Return
m_direccion
End Get
Set(ByVal Value As String)
m_direccion = Value
End Set
End Property
Public Property Ciudad(ByVal
Esp As Boolean)
As String
Get
Return
m_ciudad
End Get
Set(ByVal Value As String)
m_ciudad = Value
End Set
End Property
'Esp es true si el CP es español, en ese caso valida a 5
posiciones, si esp es False CP extranjero permite cualquier longitud.
Public Property CP(ByVal Esp As Boolean) As String
Get
Return
m_cp
End Get
Set(ByVal Value As String)
If
Esp = True Then
If
Len(Value) = 5 Then
m_cp = Value
Else
MsgBox("El Código postal debe tener 5
carácteres")
End If
Else
m_cp = Value
End
If
End Set
End Property
Public Property Provincia() As
String
Get
Return
m_provincia
End Get
Set(ByVal Value As String)
m_provincia = Value
End Set
End Property
Public Property Observaciones() As
String
Get
Return
m_observaciones
End Get
Set(ByVal Value As String)
m_observaciones = Value
End Set
End Property
Public Property Activo() As Boolean
Get
Return
m_activo
End Get
Set(ByVal Value As Boolean)
m_activo = Value
End Set
End Property
End Class
HOLA
ResponderEliminarSOY MUY NOVATO EN VISUAL ESTUDIO Y YA PROGRAME VARIAS APLICACIONES EN FOXPRO Y ME PREPARE EL CODIGO PARA CALCULAR EL DNI, NIF PERO NO ENGO CLARO TU CODIGO PARA VB.NET
YO TENGO DOS CAMPOS, EL 1º DOND ELIJO QUE TIPO DE DOCUMENTO ES Y EL 2º EL QUE CALCULA.
EN TU EJEMPLO ME GUSTARIA VER EN PROYECTO COMO ES PARA PROBARLO, SI CABE SEA POSIBILIDAD ME LO PRODRIS MANDAR A FALONSOGP@GMAIL.COM.
MUCHAS GRACIAS
Muchas gracias!
ResponderEliminar