Hola Manuel
Esta es la función que uso para comprobar el código IBAN.
LPARAMETERS pCuenta, pControl
*!* LLAMADA A LA FUNCION
*!* THISFORM.clsCartera1.Cuenta_IBAN(Cuenta, Control)
LOCAL lnRep, ;
lnLong, lnLongitud, lxCuentaPais, lxLetra, lxPais, ;
lxPaso1, lxPaso2, lxPaso3, lxPaso3a, lxMaesfiban
** SI SOLO SE LE PASA UN PARAMETRO, CONTROLA EL TAMAÑO DE LA CUENTA
** EN CASO CONTRARIO, CONTROLA LO QUE EL PARAMETRO LE DIGA AL REVES
IF PCOUNT() < 2
pControl = .T.
ELSE
pControl = !pControl
ENDIF
THIS.Tag = ''
pCuenta = ALLTRIM(STRTRAN(pCuenta, ' '))
lxCuentaPais = '3456789012345678901234567890'
** COMPRUEBA QUE LA LONGITUD CORRESPONDA CON EL PAIS
IF pControl
lnLong = LEN(pCuenta)
lxPais = LEFT(pCuenta, 2)
DO CASE
CASE lxPais == 'AL' && Albania
lnLongitud = 28
CASE lxPais == 'AD' && Andorra
lnLongitud = 24
CASE lxPais == 'AT' && Austria
lnLongitud = 20
CASE lxPais == 'BE' && Bélgica
lnLongitud = 16
CASE lxPais == 'BA' && Bosnia - Herzegovina
lnLongitud = 20
CASE lxPais == 'BG' && Bulgaria
lnLongitud = 22
CASE lxPais == 'HR' && Croacia
lnLongitud = 21
CASE lxPais == 'CY' && Chipre
lnLongitud = 28
CASE lxPais == 'CZ' && República Checa
lnLongitud = 24
CASE lxPais == 'DK' && Dinamarca
lnLongitud = 18
CASE lxPais == 'EE' && Estonia
lnLongitud = 20
CASE lxPais == 'FO' && Islas Feroe
lnLongitud = 18
CASE lxPais == 'FI' && Finlandia
lnLongitud = 18
CASE lxPais == 'FR' && Francia
lnLongitud = 27
CASE lxPais == 'GE' && Georgia
lnLongitud = 22
CASE lxPais == 'DE' && Alemania
lnLongitud = 22
CASE lxPais == 'GI' && Gibraltar
lnLongitud = 23
CASE lxPais == 'GR' && Grecia
lnLongitud = 27
CASE lxPais == 'GL' && Groenlandia
lnLongitud = 18
CASE lxPais == 'HU' && Hungría
lnLongitud = 28
CASE lxPais == 'IS' && Islandia
lnLongitud = 26
CASE lxPais == 'IE' && Irlanda
lnLongitud = 22
CASE lxPais == 'IL' && Israel
lnLongitud = 23
CASE lxPais == 'IT' && Italia
lnLongitud = 27
CASE lxPais == 'KZ' && Kazakhstan
lnLongitud = 20
CASE lxPais == 'LV' && Letonia
lnLongitud = 21
CASE lxPais == 'LB' && Libano
lnLongitud = 28
CASE lxPais == 'LI' && Liechtenstein
lnLongitud = 21
CASE lxPais == 'LT' && Lituania
lnLongitud = 20
CASE lxPais == 'LU' && Luxemburgo
lnLongitud = 20
CASE lxPais == 'MK' && Macedonia
lnLongitud = 19
CASE lxPais == 'MT' && Malta
lnLongitud = 31
CASE lxPais == 'MC' && Monaco
lnLongitud = 27
CASE lxPais == 'ME' && Montenegro
lnLongitud = 22
CASE lxPais == 'NL' && Países Bajos
lnLongitud = 18
CASE lxPais == 'NO' && Noruega
lnLongitud = 15
CASE lxPais == 'PL' && Polonia
lnLongitud = 28
CASE lxPais == 'PT' && Portugal
lnLongitud = 25
CASE lxPais == 'RO' && Romania
lnLongitud = 24
CASE lxPais == 'SM' && San Marino
lnLongitud = 27
CASE lxPais == 'RS' && Serbia
lnLongitud = 22
CASE lxPais == 'SK' && República Eslovaca
lnLongitud = 24
CASE lxPais == 'SI' && Eslovenia
lnLongitud = 19
CASE lxPais == 'ES' && España
lnLongitud = 24
CASE lxPais == 'SE' && Suecia
lnLongitud = 24
CASE lxPais == 'CH' && Suiza
lnLongitud = 21
CASE lxPais == 'TR' && Turquía
lnLongitud = 26
CASE lxPais == 'GB' && Reino Unido
lnLongitud = 22
CASE lxPais == 'MU' && Islas Mauricio
lnLongitud = 30
CASE lxPais == 'TN' && Tunez
lnLongitud = 24
ENDCASE
IF lnLong <> lnLongitud
lxCuentaPais = LEFT(lxPais + lxCuentaPais, lnLongitud)
THIS.Tag = ''
FOR lnRep = 1 TO lnLongitud STEP 4
THIS.Tag = THIS.Tag + SUBSTR(lxCuentaPais, lnRep, 4) + ' '
ENDFOR
THIS.Tag = 'La longitud de la cuenta IBAN no se corresponde con el estandar del pais.' + ;
CHR(13) + lxPais + ' = ' + STR(lnLongitud, 2) + ' dígitos.' + CHR(13) + ;
'Ejemplo : ' + THIS.Tag
RETURN .F.
ENDIF
ENDIF
lxPaso1 = SUBSTR(pCuenta, 5) + LEFT(pCuenta, 4)
lnLong = LEN(lxPaso1)
lxPaso2 = ''
FOR lnRep = 1 TO lnLong
lxLetra = SUBSTR(lxPaso1, lnRep, 1)
IF ISDIGIT(lxLetra)
lxPaso2 = lxPaso2 + lxLetra
ELSE
lxPaso2 = lxPaso2 + STR(ASC(lxLetra) - 55, 2, 0)
ENDIF
ENDFOR
lnLong = LEN(lxPaso2)
lxPaso3a = ''
FOR lnRep = 1 TO lnLong
lxPaso3a = lxPaso3a + SUBSTR(lxPaso2, lnRep, 1)
IF LEN(lxPaso3a) = 9 OR lnRep = lnLong
lxPaso3 = VAL(lxPaso3a) % 97
IF lnRep < lnLong
lxPaso3a = ALLTRIM(STR(lxPaso3, 2, 0))
ENDIF
ENDIF
ENDFOR
** SI SE PIDE EL CODIGO IBAN DE UNA NUEVA CUENTA NACIONAL, LO DEVUELVE
** EN CASO CONTRARIO, DEVUELVE LA VALIDEZ DEL CODIGO IBAN INTEGRO
IF LEFT(pCuenta, 4) == 'ES00'
lxMaesfiban = 'ES' + PADL(INT(98 - lxPaso3), 2, '0')
RETURN lxMaesfiban
ELSE
RETURN (lxPaso3 = 1)
ENDIF
El funcionamiento es el siguiente: le paso el código de la cuenta que quiero comprobar/calcular, con el IBAN delante; ej: ES0012345678901234567890. El segundo parámetro se usa en un caso especial e indica si debe comprobar además la longitud de la cuenta en algunos países europeos: FALSE no comprueba, TRUE sí lo hace; por eso invierte el parámetro ya que la mayoría de las llamadas a la función le pasaba sólo la cuenta. Si es errónea la guarda en el TAG de la clase para mostrarla en el programa.
El segundo bloque realiza la comprobación en sí: quita los dígitos de control del IBAN y el código lo mete al final; convierte las letras en números y le aplica el módulo 97 (lo hace en varios pasos porque el valor resultante era demasiado grande).
Finalmente, si el código IBAN que le paso es ES00, me devuelve el código IBAN correcto (así puedo usar la misma función para calcular el IBAN de las antiguas CCC). En caso contrario, devuelve TRUE si el cálculo ha sido correcto; así en el programa puedo analizar la validez del código de cuenta.
El segundo parámetro lo uso para que no copruebe la longitud de la cuenta y poder calcular el código IBAN del Identificador de la cuenta bancaria para los Adeudos, ya que el antiguo sufijo se convierte en una única cadena formada por el IBAN, el sufijo y el CIF, con el formato ESXXSSSCCCCCCCCC.
Espero que te sirva.