2014/06/02

Convertir números a letras en SQL Server

Función para poder convertir un monto numérico en un monto en letras, muy útil si se quiere hacer una descripción de un monto para alguna factura o boleta. Primero crearemos la función llamada "fn_ConvertirNumeroLetras" que recibe 2 parámetros, uno es el numero que deseamos convertir a letras y el otro el nombre de la moneda que deseamos concatenarlo al monto.
 
/*********************************************************************************
  NOMBRE:        fn_ConvertirNumeroLetra
  PROPOSITO: CONVERTIR NUMEROS A LETRAS.
  VERSIONES:
      Ver      Fecha        Autor               Descripción (inc. Req/inc)
     ------  ----------  ---------------    ------------------------------------
      1.0    01/06/2014  EDGAR CALZADA      CREACION
 *********************************************************************************/
 CREATE FUNCTION fn_ConvertirNumeroLetra
 (
        @Numero     NUMERIC(18, 2),
        @Moneda     VARCHAR(100)
 )
 RETURNS VARCHAR(512)
 AS
 BEGIN
        DECLARE @lnEntero       INT,
                @lcRetorno      VARCHAR(512),
                @lnTerna        INT,
                @lcMiles        VARCHAR(512),
                @lcCadena       VARCHAR(512),
                @lnUnidades     INT,
                @lnDecenas      INT,
                @lnCentenas     INT,
                @lnFraccion     INT,
                @resultado      AS VARCHAR(512)
       
        SELECT @lnEntero = CAST(@Numero AS INT),
               @lnFraccion     = (@Numero - @lnEntero) * 100,
               @lcRetorno      = '',
               @lnTerna        = 1
       
        WHILE @lnEntero > 0
        BEGIN
            /* WHILE */
            -- Recorro terna por terna      
            SELECT @lcCadena = ''          
            SELECT @lnUnidades = @lnEntero % 10            
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)          
            SELECT @lnDecenas = @lnEntero % 10      
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)          
            SELECT @lnCentenas = @lnEntero % 10            
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)
            -- Analizo las unidades        
            SELECT @lcCadena = CASE /* UNIDADES */
                                    WHEN @lnUnidades = 1 AND @lnTerna = 1 THEN
                                         'UNO ' + @lcCadena
                                    WHEN @lnUnidades = 1 AND @lnTerna <> 1 THEN
                                         'UN ' + @lcCadena
                                    WHEN @lnUnidades = 2 THEN 'DOS ' + @lcCadena
                                    WHEN @lnUnidades = 3 THEN 'TRES ' + @lcCadena
                                    WHEN @lnUnidades = 4 THEN 'CUATRO ' + @lcCadena
                                    WHEN @lnUnidades = 5 THEN 'CINCO ' + @lcCadena
                                    WHEN @lnUnidades = 6 THEN 'SEIS ' + @lcCadena
                                    WHEN @lnUnidades = 7 THEN 'SIETE ' + @lcCadena
                                    WHEN @lnUnidades = 8 THEN 'OCHO ' + @lcCadena
                                    WHEN @lnUnidades = 9 THEN 'NUEVE ' + @lcCadena
                                    ELSE @lcCadena
                               END /* UNIDADES */
            -- Analizo las decenas
            SELECT @lcCadena = CASE /* DECENAS */
                                    WHEN @lnDecenas = 1 THEN CASE @lnUnidades
                                                                  WHEN 0 THEN
                                                                       'DIEZ '
                                                                  WHEN 1 THEN
                                                                       'ONCE '
                                                                  WHEN 2 THEN
                                                                       'DOCE '
                                                                  WHEN 3 THEN
                                                                       'TRECE '
                                                                  WHEN 4 THEN
                                                                       'CATORCE '
                                                                  WHEN 5 THEN
                                                                       'QUINCE '
                                                                  ELSE 'DIECI' + @lcCadena
                                                             END
                                    WHEN @lnDecenas = 2 AND @lnUnidades = 0 THEN
                                         'VEINTE ' + @lcCadena
                                    WHEN @lnDecenas = 2 AND @lnUnidades <> 0 THEN
                                         'VEINTI' + @lcCadena
                                    WHEN @lnDecenas = 3 AND @lnUnidades = 0 THEN
                                         'TREINTA ' + @lcCadena
                                    WHEN @lnDecenas = 3 AND @lnUnidades <> 0 THEN
                                         'TREINTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 4 AND @lnUnidades = 0 THEN
                                         'CUARENTA ' + @lcCadena
                                    WHEN @lnDecenas = 4 AND @lnUnidades <> 0 THEN
                                         'CUARENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 5 AND @lnUnidades = 0 THEN
                                         'CINCUENTA ' + @lcCadena
                                    WHEN @lnDecenas = 5 AND @lnUnidades <> 0 THEN
                                         'CINCUENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 6 AND @lnUnidades = 0 THEN
                                         'SESENTA ' + @lcCadena
                                    WHEN @lnDecenas = 6 AND @lnUnidades <> 0 THEN
                                         'SESENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 7 AND @lnUnidades = 0 THEN
                                         'SETENTA ' + @lcCadena
                                    WHEN @lnDecenas = 7 AND @lnUnidades <> 0 THEN
                                         'SETENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 8 AND @lnUnidades = 0 THEN
                                         'OCHENTA ' + @lcCadena
                                    WHEN @lnDecenas = 8 AND @lnUnidades <> 0 THEN
                                         'OCHENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 9 AND @lnUnidades = 0 THEN
                                         'NOVENTA ' + @lcCadena
                                    WHEN @lnDecenas = 9 AND @lnUnidades <> 0 THEN
                                         'NOVENTA Y ' + @lcCadena
                                    ELSE @lcCadena
                               END /* DECENAS */
            -- Analizo las centenas        
            SELECT @lcCadena = CASE /* CENTENAS */
                                    WHEN @lnCentenas = 1 AND @lnUnidades = 0 AND @lnDecenas
                                         = 0 THEN 'CIEN ' +
                                         
                                         @lcCadena
                                    WHEN @lnCentenas = 1 AND NOT(@lnUnidades = 0 AND @lnDecenas = 0) THEN
                                         'CIENTO ' + @lcCadena
                                    WHEN @lnCentenas = 2 THEN 'DOSCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 3 THEN 'TRESCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 4 THEN 'CUATROCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 5 THEN 'QUINIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 6 THEN 'SEISCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 7 THEN 'SETECIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 8 THEN 'OCHOCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 9 THEN 'NOVECIENTOS ' + @lcCadena
                                    ELSE @lcCadena
                               END /* CENTENAS */
            -- Analizo la terna
           
            SELECT @lcCadena = CASE /* TERNA */
                                    WHEN @lnTerna = 1 THEN @lcCadena
                                    WHEN @lnTerna = 2 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0) THEN
                                         @lcCadena + ' MIL '
                                    WHEN @lnTerna = 3 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0)
                                         AND
                                         
                                         @lnUnidades = 1 AND @lnDecenas = 0 AND @lnCentenas
                                         = 0 THEN @lcCadena + 'MILLON '
                                    WHEN @lnTerna = 3 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0)
                                         AND
                                         NOT (@lnUnidades = 1 AND @lnDecenas = 0 AND @lnCentenas = 0) THEN
                                         @lcCadena
                                         + ' MILLONES '
                                    WHEN @lnTerna = 4 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0) THEN
                                         @lcCadena + ' MIL MILLONES '
                                    ELSE ''
                               END /* TERNA */
            -- Armo el retorno terna a terna        
            SELECT @lcRetorno = @lcCadena + @lcRetorno      
            SELECT @lnTerna = @lnTerna + 1
        END /* WHILE */        
        IF @lnTerna = 1
            SELECT @lcRetorno = 'CERO'
       
        SELECT @resultado = RTRIM(@lcRetorno) + ' CON ' + LTRIM(STR(@lnFraccion, 2))
               + '/100 ' + @Moneda
       
        RETURN @resultado
 END
 GO
 
 -- Para ejecutarlo solo nos bastara con llamar a la función y pasarle los 2 parámetros mencionados.
 SELECT [dbo].fn_ConvertirNumeroLetra(125.50, 'Nuevos Soles')
 -- Esto nos dará como resultado lo siguiente.
 -- CIENTO VEINTICINCO CON 50/100 Nuevos Soles