Conversión de Números a
Letras con Transact-SQL
Leonel Morales Díaz
Ingeniería Simple
[email protected]
Copyright 2008 by Leonel Morales Díaz – Ingeniería Simple.
Derechos reservados
Disponible en: http://www.ingenieriasimple.com/TSQL
Conversión de números a letras
• Se trata de convertir un número a las
palabras y letras con que se escribe
– 328 = trescientos veintiocho
• Inicialmente solo enteros
• Después también números de punto
flotante
– 45.89 = cuarenta y cinco con 89/100
Problemas
• El 1 (uno) final no se escribe igual
– 31,428 = treinta y un mil cuatrocientos
veintiocho
– 131 = ciento treinta y uno
• El uno final debe coincidir en género
– 21 libras = veintiuna libras
– 41 kilos = cuarenta y un kilos
• ¿Qué sigue después de trillones?
Números “simples”
•
•
•
•
•
•
Del 1 al 20
De 10 en 10 del 30 al 100
Conversión es directa
El 1 es especial
Por eso regresa ‘un(o’
Debe ser procesado al final
CREATE FUNCTION Convi_FindNum
( @Cual Int )
RETURNS nVarChar(Max)
AS BEGIN
Declare @Resu nVarChar(Max)
Set @Resu = Case @Cual
When 1 Then 'un(o'
When 2 Then 'dos'
When 3 Then 'tres'
When 4 Then 'cuatro'
When 5 Then 'cinco'
When 6 Then 'seis'
When 7 Then 'siete'
When 8 Then 'ocho'
When 9 Then 'nueve'
When 10 Then 'diez'
When 11 Then 'once'
When 12 Then 'doce'
When 13 Then 'trece'
When 14 Then 'catorce'
When 15 Then 'quince'
When 16 Then 'dieciseis'
When 17 Then 'diecisiete'
When 18 Then 'dieciocho'
When 19 Then 'diecinueve'
When 20 Then 'veinte'
When 30 Then 'treinta'
When 40 Then 'cuarenta'
When 50 Then 'cincuenta'
When 60 Then 'sesenta'
When 70 Then 'setenta'
When 80 Then 'ochenta'
When 90 Then 'noventa'
When 100 Then 'cien'
Números “no simples”
•
•
•
Requieren un reproceso
Puede ser recursivo
“*” significa:
–
–
–
–
–
–
Quite un dígito
Reprocese el resto
728 => setecientos *, 28
28 => veinti*, 8
8 = > ocho
Sustituya el * por el
resultado del reproceso
– Setecientos *
– Setecientos veinti*
– Setecientos veintiocho
•
“#” es similar pero en el
prefijo
Else Case
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
When @Cual
Else ''
End
End
RETURN @Resu
END
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
29 Then 'veinti*'
39 Then 'treinta y *'
49 Then 'cuarenta y *'
59 Then 'cincuenta y *'
69 Then 'sesenta y *'
79 Then 'setenta y *'
89 Then 'ochenta y *'
99 Then 'noventa y *'
199 Then 'ciento *'
299 Then 'doscientos *'
399 Then 'trescientos *'
499 Then 'cuatrocientos *'
599 Then 'quinientos *'
699 Then 'seiscientos *'
799 Then 'setecientos *'
899 Then 'ochocientos *'
999 Then 'novecientos *'
1999 Then 'un mil *'
9999 Then '# mil *'
99999 Then '## mil *'
999999 Then '### mil *'
1999999 Then 'un millón *'
9999999 Then '# millones *'
99999999 Then '## millones *'
999999999 Then '### millones *'
Función de reproceso
•
•
Llama a la primera función
Puede llamarse
recursivamente
– Dependiendo de si hay
prefijos o sufijos por
procesar
CREATE FUNCTION Convi_PreConvierte
( @Cual Int )
RETURNS nVarChar(Max)
AS BEGIN
Declare @Resu nVarChar(Max)
Set @Resu = ''
If @Cual <= 0 Return @Resu
Set @Resu = dbo.Convi_FindNum(@Cual)
Declare @TmpPre Int
Set @TmpPre = 0
Declare @TmpSuf Int
Set @TmpSuf = @Cual
Declare @i Int
Declare @TmpNum nVarChar(Max)
Set @i = Case
When CharIndex('###',@Resu) > 0 Then 3
When CharIndex('##',@Resu) > 0 Then 2
When CharIndex('#',@Resu) > 0 Then 1
Else 0
End
If @i > 0 Begin
Set @TmpNum = Convert(nVarChar(Max),@Cual)
Set @TmpPre = Convert(Int,Left(@TmpNum,@i))
Set @Resu = Right(@Resu,Len(@Resu)[email protected])
Set @TmpSuf = Convert(Int,Right(@TmpNum,Len(@TmpNum)[email protected]))
End
If CharIndex('*',@Resu) > 0 Begin
If @TmpPre > 0
Set @Resu = dbo.Convi_PreConvierte(@TmpPre) +
Left(@Resu,Len(@Resu)-1) + dbo.Convi_PreConvierte(@TmpSuf)
Else Begin
Set @TmpNum = Convert(nVarChar(Max),@TmpSuf)
Set @TmpSuf = Convert(Int,Right(@TmpNum,Len(@TmpNum)-1))
Set @Resu = Left(@Resu,Len(@Resu)-1) +
dbo.Convi_PreConvierte(@TmpSuf)
End
End Else
If @TmpPre > 0
Set @Resu = dbo.Convi_PreConvierte(@TmpPre) + @Resu
RETURN @Resu
END
Función de entrada
•
•
•
Recibe el número a convertir
Llama a la función de reproceso
Revisa si hay que cambiar el uno
CREATE FUNCTION Convi_Convierte
( @Cual Int )
RETURNS nVarChar(Max)
AS BEGIN
Declare @Resu nVarChar(Max)
Set @Resu = dbo.Convi_PreConvierte(@Cual)
If Right(@Resu,4) = 'un(o'
Set @Resu = Left(@Resu,Len(@Resu)-4) + 'uno'
Set @Resu = Replace(@Resu,'un(o','un')
RETURN @Resu
END
Función para punto flotante
•
Divide el número en dos
– La parte entera, proceso normal
– La parte decimal, proceso especial
CREATE FUNCTION Convi_EnLetras
( @Cual Float )
RETURNS nVarChar(Max)
AS BEGIN
Declare @TmpFloat Float
Set @TmpFloat = Round(@Cual,2)
Declare @Decs nVarChar(Max)
Set @Decs = Right('00' + Convert(nVarChar(Max),Round((@TmpFloat - Floor(@TmpFloat))*100,0)),2)
Declare @Resu nVarChar(Max)
Set @Resu = dbo.Convi_Convierte(Floor(@TmpFloat)) + ' con ' + @Decs + '/100'
RETURN @Resu
END
Algunos ejemplos de llamadas
Select dbo.Convi_FindNum(342) As FindNum
GO
Select dbo.Convi_PreConvierte(51421) As PreConvierte
GO
Select dbo.Convi_Convierte(121471) As Convierte
GO
Select dbo.Convi_EnLetras(46372.60) As EnLetras
GO
FindNum
--------------------trescientos *
(1 row(s) affected)
PreConvierte
--------------------cincuenta y un(o mil cuatrocientos veintiun(o
(1 row(s) affected)
Convierte
--------------------ciento veintiun mil cuatrocientos setenta y uno
(1 row(s) affected)
EnLetras
--------------------cuarenta y seis mil trescientos setenta y dos con 60/100
(1 row(s) affected)
Descargar

Convi - Ingeniería Simple