Validar dni España

291 views
Skip to first unread message

José Luis

unread,
Sep 19, 2022, 5:03:00 PM9/19/22
to Comunidad de Visual Foxpro en Español
Hola,

Llevo un rato buscando, pero no encuentro ninguna función que funcione para validar los nif, nie, cif de España.

Agradeceré si alguien me puede facilitar una.

Muchas Gracias foro

Antonio Lima

unread,
Sep 19, 2022, 5:53:19 PM9/19/22
to publice...@googlegroups.com
Hola Jose Luis,

he encontrado este enlace, yo no lo he probado.


pero a lo mejor puede ayudarte.

Un saludo,

--
Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/cba7d0c3-e724-4763-a646-260706a29e6fn%40googlegroups.com.

Fernando Puyuelo Ossorio

unread,
Sep 20, 2022, 4:29:15 PM9/20/22
to Comunidad de Visual Foxpro en Español
te paso una rutina que usamos en BORSAN hace muchos años, que hemos ido depurando con el tiempo.
Te he puesto un ejemplo rápido.
Creo no haberme equivocado en nada.
El código yo lo refactorizaría completo, pero bueno, eso ya te lo dejo a ti :-)


lcNif = "00000001"
lcNifResultante = CalculaNif(lcNif,.T.)
? lcNifResultante && -> "00000001R



*---------------------------------------------------------
*    Método:
*        CALCULANIF
*    Parameters: tcValor: Valor
*                tlSustituirValor: Sustituir el valor a la vuelta, es decir, poner el resultado que nos de en el value del objeto llamante
*
*    Objetivo:
*        Comprueba el NIF y retorna el nif corecto
*!*    CIF.- Si empieza por las letras {N,P,Q,R,S,V}, el dígito es una letra A-J
*!* CIF.- Si empieza por las letras {A-H,J,U,W}, el dígito es un numero del 0-9
*!*    CIF.- Si empieza por las letras {K,L,M}, el dígito una letra calculada como el DNI

*!* Ver: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal

*    Programador:
*        informática Borsan
*    Fecha de Terminación:
*        23/05/01 18:34:40
*---------------------------------------------------------

PROCEDURE CalculaNif

LPARAMETERS tcValor, tlSustituirValor

LOCAL llRetorno
LOCAL lcCadena, lcCaracter, lcNumero, lcLetras, lcSalida, lcEntrada, lcNumeroCalc, lcPrimero
LOCAL lnInd, lnLong, lnValor
LOCAL llAct, llRetorno
LOCAL lcMsg, lcMsgBox, lcMensaje
LOCAL lcLetrasCIF

PRIVATE pnA ,pnB, pnDigito , pcDigito, plError
STORE 0 TO pnA, pnB, pnDigito
pcDigito = ''
plError = .F.

STORE '' TO lcCadena, lcCaracter, lcNumero, lcLetras, lcSalida, lcEntrada, lcNumeroCalc, lcPrimero,lcMsg, lcMsgBox, lcMensaje
STORE 0 TO lnInd, lnLong, lnValor
STORE .F. TO llAct, llRetorno
llRetorno = .T.
tlSustituirValor = IIF(PCOUNT() = 1, .T., tlSustituirValor)
llAct = !EMPTY(NVL(tcValor, ""))
lcLetrasCIF = 'ABCDEFGHIJ'

IF !llAct
    llRetorno = .F.
ENDIF

llAct = llAct AND tlSustituirValor



TRY
    IF llRetorno
        IF LEN(ALLTRIM(tcValor)) < 5    
            =MESSAGEBOX(txt('NIF/CIF incorrecto. Introdúzcalo de nuevo.'),oCte.ExclamacionIcon + oCte.OkOnly, oCte.Nom_Aplicacion)
            llRetorno = .F.
        ENDIF
    ENDIF
   
   
    IF llRetorno

        tcValor = ALLTRIM(UPPER(tcValor))
        lcEntrada = tcValor
        * quitar todo lo que no sea letras o numeros.
        FOR lnInd = 1 TO LEN(lcEntrada)
            lcCaracter = SUBSTR(lcEntrada, lnInd, 1)
            IF (ISALPHA(lcCaracter) OR ISDIGIT(lcCaracter))
                lcCadena = lcCadena + lcCaracter
            ENDIF
        ENDFOR

        lcEntrada = lcCadena        && lcEntrada es tcEntrada sin signos de puntuación y similares

        lcPrimero = LEFT(lcEntrada, 1)


        IF AT(lcPrimero, "KLMXYZ") > 0 OR ISDIGIT(lcPrimero)
            ***************************************************************************
            *    N.I.F. = Número de Identificación Fiscal para persona Físicas        *
            ***************************************************************************
            lcLetras = 'TRWAGMYFPDXBNJZSQVHLCKE'
            lcCadena = ''
            lcSalida = ''
            lnLong = LEN(lcEntrada)
            lcNumero = ''
            lcNumeroCalc = ''        
            FOR lnInd = 1 TO lnLong
                lcCaracter = SUBSTR(lcEntrada, lnInd, 1)
                IF ISDIGIT(lcCaracter)
                    lcNumero = lcNumero + lcCaracter
                ENDIF
            ENDFOR

            lcNumeroCalc = lcNumero        

            * Desde el 08/10/20008 se le ha agotado la numeración con la X a la AEAT,
            * con lo cual desde esa fecha todas las solicitudes que se acepten de NIE empezaran con la "Y".

            *!* Modificado : 05/11/2008 por Pedro (PEDRO). Nuevas letras y su control en los N.I.E.
            * La Orden INT/2058/2008, crea las nuevas letras de N.I.E. de las personas físicas extranjeras "Y" y "Z",
            * en lugar de la "X", al haberse agotado la capacidad de numeración de esta ésta última.
            * La única peculiaridad a resaltar referida a esta configuración de NIEs que comiencen por "Y" o "Z"
            * consiste en que el algoritmo de cálculo del carácter de control será el mismo que para la letra "X",
            * con la diferencia de que la letra inicial (X,Y,Z) tendrá un peso (0,1,2 respectivamente),
            * que habrá que concatenar con la parte numérica del NIE para formar el número base a dividir por 23.
            * (Nota: la asignación de un peso cero a la letra X equivale a decir que dicha letra no se tiene en cuenta
            * en el algoritmo de cálculo de carácter de control).

            lcSalida = IIF(AT(lcPrimero, "XYZKLM") > 0, lcPrimero, "")

            lcNumeroCalc = PADL(ICASE(AT(lcPrimero, "XKLM") > 0, "0", lcPrimero = "Y", "1", lcPrimero = "Z", "2", "") + lcNumero, 8, "0")


            * Cálculo de la letra
            lnValor = VAL(lcNumeroCalc)
            lnLong = INT(lnValor / 23) * 23
            lnInd = (lnValor - lnLong) + 1
            lcSalida = lcSalida + lcNumero + SUBSTR(lcLetras, lnInd, 1)

        ELSE        && This.NIF
            ***************************************************************************
            *                               C.I.F.                                    *
            ***************************************************************************
            *!*    Si empieza por las letras {N,P,Q,R,S,V}, el dígito es una letra A-J
            *!* Si empieza por las letras {A-H,J,U,W}, el dígito es un numero del 0-9
            *!* Modificado : 26/11/2012 14:12:16 por Rafael (WIN8X64)
            *!*    Faltaba la 'V'
            * Control de la posibles letras por las que empiezan los CIF
            IF INLIST(LEFT(lcEntrada,1),'A','B','C','D','E','F','G','H','N','P','Q','S','R', 'J', 'U', 'V', 'W')
                * A Sociedades Anónimas
                * B Sociedades de Responsabilidad Limitada
                * C Sociedades Colectivas
                * D Sociedades Comanditarias
                * E Comunidades de bienes
                * F Sociedades Cooperativas
                * G Asociaciones y otros tipos no definidos
                * H Comunidades de propietarios en régimen de propiedad horizontal
                * K, L, M corresponden al formato antiguo
                * N. Entidades no residentes.
                * P. Corporaciones locales.
                * Q. Organismos autónomos, estatales o no, y asimilados, y congregaciones e instituciones religiosas.
                * S. Órganos de la Administración del Estado y comunidades autónomas
                * V. Sociedad Agraria de Transformación.
                STORE 0 TO pnA, pnB, pnDigito, lnInd
                pcDigito = ''
                plError = .F.

                * Control que las posiciones 2 a 8 deben ser numericas.
                FOR lnInd = 2 TO 8
                    IF !(SUBSTR(lcEntrada, lnInd, 1) >= '0' AND SUBSTR(lcEntrada, lnInd, 1) <= '9')
                        plError = .T.
                    ENDIF
                NEXT


                IF plError
                    * propone "CIF ERRONEO" como CIF calculado.
                    * lcSalida =  "CIF ERRONEO"
                    =MESSAGEBOX(txt('NIF/CIF incorrecto. Introdúzcalo de nuevo.'),oCte.ExclamacionIcon + oCte.OkOnly, oCte.Nom_Aplicacion)

                    *!* NO HACEMOS QUE SEA ERRONEO, para dejar introducir datos de cif extranjeros como portugal
                    *!*                     llRetorno = .F.
                    *!*                     llAct = .F.
                    lcSalida = lcEntrada
                    llRetorno = .T.

                ELSE
                    * Suma las posiciones pares (sin contar la letra inicial)
                    pnA = VAL(SUBSTR(lcEntrada,3,1)) + VAL(SUBSTR(lcEntrada,5,1)) + VAL(SUBSTR(lcEntrada,7,1))

                    * Suma las posiciones impares (sin contar la letra inicial) : Multiplica por 2 y suma los 2 dígitos.
                    pnB = 0
                    FOR lnInd = 2 TO 8 STEP 2
                        pnDigito = VAL(SUBSTR(lcEntrada, lnInd, 1)) * 2
                        pcDigito = PADL(ALLTRIM(STR(pnDigito)), 2, '0')
                        pnB      = pnB + VAL(SUBSTR(pcDigito, 1, 1)) + VAL(SUBSTR(pcDigito, 2, 1))
                    NEXT

                    pnDigito = pnA + pnB
                    pnDigito = VAL(RIGHT(ALLT(STR(pnDigito)), 1))
                    pnDigito = 10 - pnDigito

                    *!* Calcular cuál ha de ser el dígito de control
                    * Si comienza por 'P' (ésto no es muy seguro) debe ser una letra que se corresponde con la
                    * siguiente relación: A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, I=9, J=0
                    *!* El dígito de control será una letra si empieza por K, P, Q, ó S.
                    *!*    Si empieza por las letras {N,P,Q,R,S,W}, el dígito es una letra A-J
                    *!* Si empieza por las letras {A-H,J,U,V}, el dígito es un numero del 0-9
                    IF INLIST(SUBSTR(lcEntrada, 1, 1),'N','P','Q','R','S','W')
                        *!* Modificado : 19.11.04 por Pedro (PEDRO). Si pnDigito = 10 no le ponía la letra 'J'
                        * IF pnDigito = 0
                        IF pnDigito = 0 OR pnDigito = 10
                            pcDigito = 'J'
                        ELSE
                            pcDigito = SUBSTR(lcLetrasCIF, pnDigito, 1)
                        ENDIF
                    ELSE

                        pcDigito = RIGHT(ALLT(STR(pnDigito)), 1)  && PARA 10 dejamos 0
                    ENDIF

                    lcSalida = LEFT(lcEntrada, 8) + pcDigito

                ENDIF
            ELSE

                IF MESSAGEBOX(txt('El valor introducido no se evalúa como CIF. ¿Desea mantener el valor?'),oCte.wi_icointerrog+oCte.wi_sino,oCte.Nom_Aplicacion) = oCte.wir_si
                    lcSalida = lcEntrada
                    llRetorno = .T.
                ELSE
                    lcSalida = ' '
                    llRetorno = .F.

                     llAct = .F.

                ENDIF
            ENDIF
        ENDIF
    ENDIF && llRetorno

    IF llRetorno

        IF lcSalida <> tcValor AND llAct AND !EMPTY(lcSalida) AND tlSustituirValor
            lcMsg = txt('El NIF/CIF calculado es diferente al introducido.') + CHR(13) + CHR(10) + ;
                txt("Valor introducido")+": " + tcValor + CHR(13) + CHR(10) +    txt("Valor calculado")+": " + lcSalida + CHR(13) + CHR(10)+ ;
                txt("¿Desea aceptar el nuevo valor? ")
            IF MESSAGEBOX(lcMsg,oCte.wi_icointerrog+oCte.wi_sino,oCte.Nom_Aplicacion) = oCte.wir_si
                *!*
            ELSE
                llAct = .F.
            ENDIF
        ENDIF
    ENDIF


CATCH TO loErr
    oApp.ERROR(loErr)
    llRetorno = .F.

FINALLY

ENDTRY

tlSustituirValor = llAct

RETURN lcSalida


Reply all
Reply to author
Forward
0 new messages