La batallita del agüelo:
Estaba preparando
la página para recogida de firmas para apoyar a Juanma, concretamente la
petición para que el gobierno español se preocupe de las investigaciones que
están haciendo sobre la enfermedad de Alexander, y quise añadirle la
comprobación de que el NIF que se indique sea el correcto, ya que si no se
indica un NIF válido, pues no vale para nada el "firmar", así que... me puse
a buscar en el código que tengo (en mi equipo y en mi sitio) sobre cómo
hacer esas comprobaciones. Y resulta que para .NET no he encontrado nada.
Todo lo que hay es para Visual Basic clásico.
Así que... he tomado parte de ese código, concretamente una función (o
procedimiento) que yo tenía, más
dos funciones de Silvia
(SGF)
de una colaboración del año 2003, las he actualizado para usarla desde
Visual Basic 2008 (aunque no uso nada especial, por tanto "supongo" que será
válido para cualquier versión).
La función para calcular la letra del NIF
Esta función es una adaptación del código que tengo desde hace ya la
friolera de 13 años (o más).
A esta función (CalculaNIF) se le pasa por parámetro el NIF a calcular,
si tiene letra y cosas que no sean números, se quitan y se calcula la letra
que le correspondería, ese valor calculado, se devuelve, pero ya con la
letra que le corresponde.
Si quieres ver el código original para Visual Basic clásico:
Cálculo de la letra
del NIF.
Private Function CalculaNIF(ByVal strA As String) As String
'----------------------------------------------------------------------
' Calcular la letra del NIF
' Código original adaptado a Visual Basic (13/Sep/95)
' Adaptado a Visual Basic .NET (VB 9.0/2008) (09/May/08)
' y convertido en función que devuelve el NIF correcto
'----------------------------------------------------------------------
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
La función para verificar o comprobar el NIF
Esta función (Verificar_NIF) está adaptada del código
publicado por SGF el 29/Jun/2003.
La he simplificado para que devuelva un valor True si es correcto el NIF y
un valor False si no lo es.
Debes tener en cuenta que el NIF que se le pasa por parámetro, para
comprobar si es un NIF correcto, NO debe tener espacios, puntos ni cualquier
otro carácter que no sean números y una letra.
En esta función se usa mi función de CalcularNIF. Aunque
en el original usaba la versión que esta mujer creó, pero como a mi me
gusta más mi código, pues... ;-)))
''' <summary>
''' Comprueba si es un NIF válido
''' No usar espacios ni separadores para la letra
''' Devuelve True si es correcto
''' </summary>
''' <remarks>
''' Adaptado de un código de SGF
''' http://www.elguille.info/colabora/vb/sgf_Verificar_NIF_CIF.htm
''' </remarks>
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
La función para verificar o comprobar el CIF
La función (Verificar_CIF) también está adaptada de la
colaboración de SGF.
También la he simplificado bastante, y para que sea coherente, también
devuelve True si es correcto el CIF indicado.
Esta función también usa mi función CalculaNIF.
''' <summary>
''' Comprueba si es un CIF
''' Devuelve True si es un CIF
''' </summary>
''' <remarks>
''' Adaptado de un código de SGF
''' http://www.elguille.info/colabora/vb/sgf_Verificar_NIF_CIF.htm
''' </remarks>
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) ' Codigo de Control
strDigit = Mid(valor, 9) ' CIF menos primera y ultima posiciones
If InStr(letras, strLetra) = 0 Then ' comprobamos la letra del CIF (1ª posicion)
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
Bueno, puesto es todo... vale, te pongo un ejemplo de cómo usar estas
funciones.
Y cuando tenga tiempo y ganas, lo convertiré a C#, que hoy ya es tarde y...
pues eso... ;-)))
Dim esCIF As Boolean = Verificar_CIF(txtDNI.Text)
If esCIF = True Then
LabelInfo.Text &= vbCrLf & "Es un CIF: " & txtDNI.Text
Else
LabelInfo.Text &= vbCrLf & "NO es un CIF: " & txtDNI.Text
End If
Dim esNIF As Boolean = Verificar_NIF(txtDNI.Text)
If esNIF Then
LabelInfo.Text &= vbCrLf & "Es un NIF: " & txtDNI.Text
Else
LabelInfo.Text &= vbCrLf & "NO es un NIF: " & txtDNI.Text
End If
Dim elNIF As String = CalculaNIF(txtDNI.Text)
If String.IsNullOrEmpty(elNIF) = False Then
LabelInfo.Text &= vbCrLf & "El NIF es: " & elNIF
End If
Espero que te sea de utilidad.
Nos vemos.
Guillermo
Espacios de nombres usados en el código de este artículo:
Microsoft.VisualBasic
System.Text