Es una modificación a la función enviada por Luis Maria Guayan, pero esta acepta Euros y Pesetas, distingue el genero (masculino o femenino) de la moneda y tiene alguna pequeña corrección.
**********************************************************************
*
* Funcion: Num2Let
*
* Convierte un numero a letras. Valido para Euros y Pesetas
*
* Sintaxis:
*
* =Num2Let(tnNumero, tlEuro, tnDecimales)
*
* Parametros:
*
* tnNumero = Número a convertir
* tlEuro (si se devuelve en Euros .T. o Pesetas .F.)
* tnDecimales (numero de decimales, por defecto 2)
*
* Ejemplos:
*
* = Num2Let(125.21, .T.)
* = Num2Let(63241, .F.)
*
* Retorno:
*
* El numero en caracter
*
* Nota:
*
* Creación : Luis Maria Guayan
* Ultima Modificacion: 27/12/2001 Juan Encinar, Oscar Fariña, Pablo Roca
**********************************************************************
FUNCTION Num2Let(tnNumero,tlEuro,tnDecimales)
LOCAL lnEntero, lnFraccion,lcRet
lcret = ''
IF PCOUNT()<2
tlEuro = .T.
ENDIF
IF tnNumero<0
lcret = 'MENOS '
tnNumero=ABS(tnNumero)
ENDIF
IF type("tnDecimales") = "L"
tnDecimales = 2
ENDIF
lnEntero = INT(tnNumero)
lnFraccion = INT((tnNumero - lnEntero) * 10^tndecimales)
lcret = lcret+N2L(lnEntero, .T., tlEuro) + IIF(MOD(lnEntero,1000000)=0 AND lnEntero > 0,' DE ','')+;
IIF(tlEuro,IIF(lnEntero=1,'UN EURO','EUROS'),IIF(lnEntero=1,'UNA PESETA','PESETAS'))+;
IIF(lnFraccion > 0,' CON '+ ;
N2L(lnFraccion, .T., .T.) + IIF(lnFraccion=1,'UN CENTIMO','CENTIMOS'),'')
RETURN lcret
ENDFUNC
*--------------------------------
* FUNCTION N2L(tnNro, tlBandera, tlMasculino)
*--------------------------------
* Convierte un número entero en letras
* Usada por Let2Num (deben estar ambas)
* USO: ? N2L(1032) -> "MIL TREINTA Y DOS"
* PARAMETROS: lnNro = Número a convertir
* : tlBandera (solo para diferenciar cuando retorna "UNO" o "UN")
* : tlMasculino (para diferenciar si la moneda es genero masculino .T. / femenino .F.)
* RETORNA: Caracter
* AUTOR: LMG
* modificada por Juan Encinar, Oscar Fariña, Pablo Roca 27/12/2001
*--------------------------------
FUNCTION N2L(tnNro, tlBandera, tlMasculino)
LOCAL lnEntero, lcRetorno, lnTerna, lcMiles, ;
lcCadena, lnUnidades, lnDecenas, lnCentenas,lcCadena2
lcCadena2 = ''
lnEntero = INT(tnNro)
lcRetorno = ''
lnTerna = 1
DO WHILE lnEntero > 0
lcCadena = ''
lnUnidades = MOD(lnEntero, 10)
lnEntero = INT(lnEntero / 10)
lnDecenas = MOD(lnEntero, 10)
lnEntero = INT(lnEntero / 10)
lnCentenas = MOD(lnEntero, 10)
lnEntero = INT(lnEntero / 10)
*--- Analizo la terna
DO CASE
CASE lnTerna = 1
lcMiles = ''
CASE lnTerna = 2 AND (lnUnidades+lnDecenas+lnCentenas # 0)
lcMiles = 'MIL '
CASE lnTerna = 3
lcMiles = IIF(lnUnidades = 1 AND lnDecenas = 0 AND ;
lnCentenas = 0, 'UN MILLON ', 'MILLONES ')
CASE lnTerna = 4 AND (lnUnidades+lnDecenas+lnCentenas # 0)
lcMiles = 'MIL '
CASE lnTerna = 5 AND (lnUnidades+lnDecenas+lnCentenas # 0)
lcMiles = IIF(lnUnidades = 1 AND lnDecenas = 0 AND ;
lnCentenas = 0, 'BILLON ', 'BILLONES ')
CASE lnTerna > 5
lcRetorno = ' ERROR: NUMERO DEMASIADO GRANDE '
EXIT
ENDCASE
*--- Analizo las unidades
DO CASE
CASE lnUnidades = 1
IF !(allt(str(tnNro)) $ "100,1000,1000000,1000000000")
IF tlMasculino
lcCadena = IIF(lnTerna = 1 AND NOT tlBandera, 'UNO ', IIF(lnCentenas#0 or lnDecenas#0,'UN ',' '))
ELSE
if lnterna = 1
lcCadena = 'UNA '
else
lcCadena = IIF(lnCentenas#0 or lnDecenas#0,'UN'+IIF(lnTerna < 3,'A ',' '),'')
endif
ENDIF
ENDIF
CASE lnUnidades = 2
lcCadena = 'DOS '
CASE lnUnidades = 3
lcCadena = 'TRES '
CASE lnUnidades = 4
lcCadena = 'CUATRO '
CASE lnUnidades = 5
lcCadena = 'CINCO '
CASE lnUnidades = 6
lcCadena = 'SEIS '
CASE lnUnidades = 7
lcCadena = 'SIETE '
CASE lnUnidades = 8
lcCadena = 'OCHO '
CASE lnUnidades = 9
lcCadena = 'NUEVE '
ENDCASE
*--- Analizo las decenas
DO CASE
CASE lnDecenas = 1
DO CASE
CASE lnUnidades = 0
lcCadena = 'DIEZ '
CASE lnUnidades = 1
lcCadena = 'ONCE '
CASE lnUnidades = 2
lcCadena = 'DOCE '
CASE lnUnidades = 3
lcCadena = 'TRECE '
CASE lnUnidades = 4
lcCadena = 'CATORCE '
CASE lnUnidades = 5
lcCadena = 'QUINCE '
OTHER
lcCadena = 'DIECI' + lcCadena
ENDCASE
CASE lnDecenas = 2
lcCadena = IIF(lnUnidades = 0, 'VEINTE ', 'VEINTI') + lcCadena
CASE lnDecenas = 3
lcCadena = 'TREINTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 4
lcCadena = 'CUARENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 5
lcCadena = 'CINCUENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 6
lcCadena = 'SESENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 7
lcCadena = 'SETENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 8
lcCadena = 'OCHENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
CASE lnDecenas = 9
lcCadena = 'NOVENTA ' + IIF(lnUnidades = 0, '', 'Y ') + lcCadena
ENDCASE
*--- Analizo las centenas
lcCadena2 = ''
DO CASE
CASE lnCentenas = 1
lcCadena2 = IIF(lnUnidades = 0 AND lnDecenas = 0, ;
'CIEN ', 'CIENTO ')
CASE lnCentenas = 2
lcCadena2 = 'DOSCIENTOS '
CASE lnCentenas = 3
lcCadena2 = 'TRESCIENTOS '
CASE lnCentenas = 4
lcCadena2 = 'CUATROCIENTOS '
CASE lnCentenas = 5
lcCadena2 = 'QUINIENTOS '
CASE lnCentenas = 6
lcCadena2 = 'SEISCIENTOS '
CASE lnCentenas = 7
lcCadena2 = 'SETECIENTOS '
CASE lnCentenas = 8
lcCadena2 = 'OCHOCIENTOS '
CASE lnCentenas = 9
lcCadena2 = 'NOVECIENTOS '
ENDCASE
IF lnTerna < 3
lcCadena2 = IIF(tlMasculino,lcCadena2,STRTRAN(lcCadena2,'TOS','TAS'))
ENDIF
lcCadena = lcCadena2+lcCadena
*--- Armo el retorno terna a terna
lcRetorno = lcCadena+lcMiles+lcRetorno
lnTerna = lnTerna + 1
ENDDO
IF lnTerna = 1
lcRetorno = 'CERO '
ENDIF
RETURN lcRetorno
ENDFUNC
*--------------------------------
Pablo Roca
Hay algún error en esta función, si la ejecutamos con ? Num2Let(100011025.22, .T., 2). El resultado es cien millones oncemil veinticincon con VEINTIUN céntimos no VEINTIDOS
ResponderBorrarBuenos días.
ResponderBorrarEn la Comunidad de VFP en Español un colega reportó inconsistencia y otro replicó.
Probé la corrección y funciona como debe ser.
javierbar...@gmail.com
4:45 (hace 5 horas)
En la funcion num2let hay algún error. Si ejecutamos
? Num2Let(100011025.22, .T., 2)
el resultado que obtenemos es
cien millones once mil veintico con VEINTIUN céntimos en lugar de veintidos. Todavía no he logrado localizar el error. Si alguien lo encuentra y lo comenta sería de agradecer.
Saludos,
Fidel Charny
7:16 (hace 3 horas)
Puedes corregir esta línea;
Original : lnFraccion = INT((tnNumero - lnEntero) * 10^tndecimales)
Modificado: lnFraccion = INT((tnNumero - lnEntero) * 10^tndecimales + 9 * 10^-(tnDecimales+2))