Expresar o convertir un número en letras

Oracle, pionero en BD relacionales.

Expresar o convertir un número en letras

Notapor Pere » Jue Ene 20, 2011 3:46 pm

En esta ocasión os dejo un código PL/SQL a modo de package que dado un número devuelve la expresión del mismo en letras. Esta funcionalidad es especialmente útil para por ejemplo poder automatizar la impresión de cheques, donde las cifras se expresan además de en su representación decimal, en su expresión escrita.

Definición
Código: Seleccionar todo

-- Programado por Pere Chardi
create or replace package expresar_en_letras is
    function numero_a_letras(numero in number) return varchar2;
end expresar_en_letras;

 


Implementación
Código: Seleccionar todo
-- Programado por Pere Chardi
create or replace package body expresar_en_letras is

    -- definicion funcion local
    function numero_menor_mil(numero in number) return varchar2;
   
    -- implementacion
    function numero_a_letras(numero in number) return varchar2 is

        fuera_de_rango EXCEPTION;

        millares_de_millon number;
        millones number;
        millares number;
        centenas number;
        centimos number;

        en_letras varchar2(200);
        entero number;

        aux varchar2(15);
    begin

        if numero < 0 or numero > 999999999999.99 then
            raise fuera_de_rango;
        end if;

        entero := trunc(numero);

        millares_de_millon := trunc(entero / 1000000000);

        millones := trunc((entero mod 1000000000) / 1000000);

        millares := trunc((entero mod 1000000) / 1000);

        centenas := entero mod 1000;

        centimos := (round(numero,2) * 100) mod 100;


        -- MILLARES DE MILLON
        if millares_de_millon = 1 then
            if millones = 0 then
                en_letras := 'mil millones ';
            else
                en_letras := 'mil ';
            end if;
        elsif millares_de_millon > 1 then

            en_letras := numero_menor_mil(millares_de_millon);

            if millones = 0 then
                en_letras := en_letras || 'mil millones ';
            else
                en_letras := en_letras || 'mil ';
            end if;
        end if;

        -- MILLONES
        if millones = 1 and  millares_de_millon = 0 then
            en_letras := 'un millón ';
        elsif millones > 0 then
            en_letras := en_letras || numero_menor_mil(millones) || 'millones ';
        end if;

        -- MILLARES
        if millares = 1 and millares_de_millon = 0 and millones = 0 then
            en_letras := 'mil ';
        elsif millares > 0 then
            en_letras := en_letras || numero_menor_mil(millares) || 'mil ';
        end if;

        -- CENTENAS
        if centenas > 0 or (entero = 0 and centimos = 0) then
            en_letras := en_letras || numero_menor_mil(centenas);
        end if;

        if centimos > 0 then
            if centimos = 1 then
                aux := 'céntimo';
            else
                aux := 'céntimos';
            end if;
            if entero > 0 then
                en_letras := en_letras || 'con ' || replace(numero_menor_mil(centimos),'uno ','un ') || aux;
            else
                en_letras := en_letras || replace(numero_menor_mil(centimos),'uno','un') || aux;
            end if;
        end if;

        return(en_letras);


    EXCEPTION
        when fuera_de_rango then
            return('Error: entrada fuera de rango');
        when others then
            raise;
    end;

    function numero_menor_mil(numero in number) return varchar2 is


        fuera_de_rango EXCEPTION;
        no_entero EXCEPTION;

        centenas number;
        decenas number;
        unidades number;

        en_letras varchar2(100);
        unir varchar2(2);

    begin

        if trunc(numero) <> numero then
            raise no_entero;
        end if;

        if numero < 0 or numero > 999 then
            raise fuera_de_rango;
        end if;


        if numero = 100 then
            return ('cien ');
        elsif numero = 0 then
            return ('cero ');
        elsif numero = 1 then
            return ('uno ');
        else
            centenas := trunc(numero / 100);
            decenas  := trunc((numero mod 100)/10);
            unidades := numero mod 10;
            unir := 'y ';

            -- CENTENAS
            if centenas = 1 then
                en_letras := 'ciento ';
            elsif centenas = 2 then
                en_letras := 'doscientos ';
            elsif centenas = 3 then
                en_letras := 'trescientos ';
            elsif centenas = 4 then
                en_letras := 'cuatrocientos ';
            elsif centenas = 5 then
                en_letras := 'quinientos ';
            elsif centenas = 6 then
                en_letras := 'seiscientos ';
            elsif centenas = 7 then
                en_letras := 'setecientos ';
            elsif centenas = 8 then
                en_letras := 'ochocientos ';
            elsif centenas = 9 then
                en_letras := 'novecientos ';
            end if;



            -- DECENAS
            if decenas = 3 then
                en_letras := en_letras || 'treinta ';
            elsif decenas = 4 then
                en_letras := en_letras || 'cuarenta ';
            elsif decenas = 5 then
                en_letras := en_letras || 'cincuenta ';
            elsif decenas = 6 then
                en_letras := en_letras || 'sesenta ';
            elsif decenas = 7 then
                en_letras := en_letras || 'setenta ';
            elsif decenas = 8 then
                en_letras := en_letras || 'ochenta ';
            elsif decenas = 9 then
                en_letras := en_letras || 'noventa ';
            elsif decenas = 1 then
                if unidades < 6 then
                    if unidades = 0 then
                        en_letras := en_letras || 'diez ';
                    elsif unidades = 1 then
                        en_letras := en_letras || 'once ';
                    elsif unidades = 2 then
                        en_letras := en_letras || 'doce ';
                    elsif unidades = 3 then
                        en_letras := en_letras || 'trece ';
                    elsif unidades = 4 then
                        en_letras := en_letras || 'catorce ';
                    elsif unidades = 5 then
                        en_letras := en_letras || 'quince ';
                    end if;
                    unidades := 0;
                else
                    en_letras := en_letras || 'dieci';
                    unir := null;
                end if;
            elsif decenas = 2 then
                if unidades = 0 then
                    en_letras := en_letras || 'veinte ';
                else
                    en_letras := en_letras || 'veinti';
                end if;
                unir := null;
            elsif decenas = 0 then
                unir := null;
            end if;

            -- UNIDADES
            if unidades = 1 then
                en_letras := en_letras || unir || 'uno ';
            elsif unidades = 2 then
                en_letras := en_letras || unir || 'dos ';
            elsif unidades = 3 then
                en_letras := en_letras || unir || 'tres ';
            elsif unidades = 4 then
                en_letras := en_letras || unir || 'cuatro ';
            elsif unidades = 5 then
                en_letras := en_letras || unir || 'cinco ';
            elsif unidades = 6 then
                en_letras := en_letras || unir || 'seis ';
            elsif unidades = 7 then
                en_letras := en_letras || unir || 'siete ';
            elsif unidades = 8 then
                en_letras := en_letras || unir || 'ocho ';
            elsif unidades = 9 then
                en_letras := en_letras || unir || 'nueve ';
            end if;
        end if;

        return(en_letras);

    EXCEPTION
        when no_entero then
            return('Error: entrada no es un número entero');
        when fuera_de_rango then
            return('Error: entrada fuera de rango');
        when others then
            raise;

    end;

end expresar_en_letras;


Test
Código: Seleccionar todo

select expresar_en_letras.numero_a_letras( 563.78 ) from dual;
select expresar_en_letras.numero_a_letras( 1034563 ) from dual;
select expresar_en_letras.numero_a_letras( 32 ) from dual;


Resultado
Código: Seleccionar todo

EXPRESAR_EN_LETRAS.NUMERO_A_LETRAS(563.78)                                     
--------------------------------------------------------------------------------
quinientos sesenta y tres con setenta y ocho céntimos                           

1 row selected.

EXPRESAR_EN_LETRAS.NUMERO_A_LETRAS(1034563)                                     
--------------------------------------------------------------------------------
un millón treinta y cuatro mil quinientos sesenta y tres                       

1 row selected.

EXPRESAR_EN_LETRAS.NUMERO_A_LETRAS(32)                                         
--------------------------------------------------------------------------------
treinta y dos                                                                   

1 row selected.



Que os aproveche.
Última edición por Pere el Vie Nov 01, 2013 4:18 pm, editado 1 vez en total
Pere
 
Mensajes: 74
Registrado: Mar Feb 02, 2010 9:44 pm

Re: Expresar o pasar un número a letras

Notapor tecnoher » Lun Sep 02, 2013 5:39 pm

Muchas gracias por el aporte, le cambié algunas cositas pero me fué de mucha utilidad, saludos
tecnoher
 
Mensajes: 1
Registrado: Lun Sep 02, 2013 5:38 pm

Re: Expresar o convertir un número en letras

Notapor alejandro.laord » Dom Sep 22, 2019 8:23 pm

Convertida en código mysql por si alguien le sirve. Lo que no he conseguido es reporducir el raise de los errores, si alguien sabe como va.... lo he intendado con signal sqlstate pero no me iba bien.
Si le paso select NUMERO_MENOR_MIL(756.55) me devuelve SETECIENTOS CINCUENTA Y SIETE
Código: Seleccionar todo
DROP FUNCTION IF EXISTS NUMERO_MENOR_MIL;
DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION `NUMERO_MENOR_MIL`(NUMERO DECIMAL(4)) RETURNS varchar(100) CHARSET utf8mb4 COLLATE utf8mb4_spanish_ci
BEGIN
       DECLARE CENTENAS INT;
       DECLARE DECENAS INT;
       DECLARE UNIDADES INT;
       DECLARE EN_LETRAS VARCHAR(100);
       DECLARE UNIR VARCHAR(2);
          SET EN_LETRAS = '';
        IF (NUMERO = 100) THEN
            RETURN ('CIEN ');
        ELSEIF NUMERO = 0 THEN
            RETURN ('CERO ');
        ELSEIF NUMERO = 1 THEN
            RETURN ('UNO ');
        ELSE
            SET CENTENAS = TRUNCATE(NUMERO / 100,0);
            SET DECENAS  = TRUNCATE((NUMERO MOD 100)/10,0);
            SET UNIDADES = NUMERO MOD 10;
            SET UNIR = 'Y ';
           
                  IF CENTENAS = 1 THEN
                SET EN_LETRAS = 'CIENTO ';
            ELSEIF CENTENAS = 2 THEN
                SET EN_LETRAS = 'DOSCIENTOS ';
            ELSEIF CENTENAS = 3 THEN
                SET EN_LETRAS = 'TRESCIENTOS ';
            ELSEIF CENTENAS = 4 THEN
                SET EN_LETRAS = 'CUATROCIENTOS ';
            ELSEIF CENTENAS = 5 THEN
                SET EN_LETRAS = 'QUINIENTOS ';
            ELSEIF CENTENAS = 6 THEN
                SET EN_LETRAS = 'SEISCIENTOS ';
            ELSEIF CENTENAS = 7 THEN
                SET EN_LETRAS = 'SETECIENTOS ';
            ELSEIF CENTENAS = 8 THEN
                SET EN_LETRAS = 'OCHOCIENTOS ';
            ELSEIF CENTENAS = 9 THEN
                SET EN_LETRAS = 'NOVECIENTOS ';
            END IF;
           
                  IF DECENAS = 3 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'TREINTA ');
            ELSEIF DECENAS = 4 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'CUARENTA ');
            ELSEIF DECENAS = 5 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'CINCUENTA ');
            ELSEIF DECENAS = 6 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'SESENTA ');
            ELSEIF DECENAS = 7 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'SETENTA ');
            ELSEIF DECENAS = 8 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'OCHENTA ');
            ELSEIF DECENAS = 9 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , 'NOVENTA ');
            ELSEIF DECENAS = 1 THEN
                IF UNIDADES < 6 THEN
                    IF UNIDADES = 0 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'DIEZ ');
                    ELSEIF UNIDADES = 1 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'ONCE ');
                    ELSEIF UNIDADES = 2 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'DOCE ');
                    ELSEIF UNIDADES = 3 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'TRECE ');
                    ELSEIF UNIDADES = 4 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'CATORCE ');
                    ELSEIF UNIDADES = 5 THEN
                        SET EN_LETRAS = CONCAT(EN_LETRAS , 'QUINCE ');
                    END IF;
                    SET UNIDADES = 0;
                ELSE
                    SET EN_LETRAS = CONCAT(EN_LETRAS, 'DIECI');
                    SET UNIR = '';
                END IF;
            ELSEIF (DECENAS = 2) THEN
                IF (UNIDADES = 0) THEN
                    SET EN_LETRAS = CONCAT(EN_LETRAS, 'VEINTE ');
                ELSE
                    SET EN_LETRAS = CONCAT(EN_LETRAS, 'VEINTI');
                END IF;
                SET UNIR = '';
            ELSEIF (DECENAS = 0) THEN
                SET UNIR = '';
            END IF;
                  
            IF (UNIDADES = 1) THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'UNO ');
            ELSEIF UNIDADES = 2 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'DOS ');
            ELSEIF UNIDADES = 3 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'TRES ');
            ELSEIF UNIDADES = 4 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'CUATRO ');
            ELSEIF UNIDADES = 5 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'CINCO ');
            ELSEIF UNIDADES = 6 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'SEIS ');
            ELSEIF UNIDADES = 7 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'SIETE ');
            ELSEIF UNIDADES = 8 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS, UNIR, 'OCHO ');
            ELSEIF UNIDADES = 9 THEN
                SET EN_LETRAS = CONCAT(EN_LETRAS , UNIR , 'NUEVE ');
            END IF;
        END IF;
        RETURN(EN_LETRAS);
    END; //


y la función principal:
Código: Seleccionar todo
DROP FUNCTION IF EXISTS NUMERO_A_LETRAS;
DELIMITER //
CREATE DEFINER=`root`@`localhost` FUNCTION NUMERO_A_LETRAS(NUMERO DECIMAL(12,2)) RETURNS VARCHAR(200)
BEGIN
   DECLARE MILLARES_DE_MILLON INT;
   DECLARE MILLONES INT;
   DECLARE MILLARES INT;
   DECLARE CENTENAS INT;
   DECLARE CENTIMOS INT;
   DECLARE EN_LETRAS VARCHAR(200);
   DECLARE ENTERO INT;
   DECLARE AUX VARCHAR(15);
   
   -- IF ((NUMERO < 0) OR (NUMERO > 999999999999.99)) THEN
    --        SIGNAL SQLSTATE '01000'
    --        SET MESSAGE_TEXT = 'CANTIDAD FUERA DE RANGO', MYSQL_ERRNO = 1000;
    -- END IF;
   SET EN_LETRAS = '';
   SET ENTERO = TRUNCATE(NUMERO,0);
   SET MILLARES_DE_MILLON = TRUNCATE(ENTERO / 1000000000,0);
   SET MILLONES = TRUNCATE((ENTERO MOD 1000000000) / 1000000,0);
   SET MILLARES = TRUNCATE((ENTERO MOD 1000000) / 1000,0);
   SET CENTENAS = ENTERO MOD 1000;
   SET CENTIMOS = (TRUNCATE(NUMERO,2) * 100) MOD 100;
   
   IF (MILLARES_DE_MILLON = 1) THEN
         IF (MILLONES = 0) THEN
               SET EN_LETRAS = 'MIL MILLONES ';
         ELSE
               SET EN_LETRAS = 'MIL ';
         END IF;
   END IF;   
   IF (MILLARES_DE_MILLON > 1) THEN
     SET EN_LETRAS = NUMERO_MENOR_MIL(MILLARES_DE_MILLON);
         IF (MILLONES = 0) THEN
               SET EN_LETRAS = CONCAT(EN_LETRAS, 'MIL MILLONES ');
         ELSE
             SET EN_LETRAS = CONCAT(EN_LETRAS, 'MIL ');
         END IF;
   END IF;
   IF ((MILLONES = 1) AND  (MILLARES_DE_MILLON = 0)) THEN
         SET EN_LETRAS = 'UN MILLÓN ';
   ELSE
      IF   (MILLONES > 0) THEN
         SET EN_LETRAS = CONCAT(EN_LETRAS, NUMERO_MENOR_MIL(MILLONES), 'MILLONES ');
      END IF;
   END IF;
   IF ((MILLARES = 1) AND (MILLARES_DE_MILLON = 0) AND (MILLONES = 0)) THEN
   SET EN_LETRAS = 'MIL ';
   ELSE
      IF (MILLARES > 0) THEN
            SET EN_LETRAS = CONCAT(EN_LETRAS , NUMERO_MENOR_MIL(MILLARES) ,'MIL ');
      END IF;
   END IF;
   IF ((CENTENAS > 0) OR ((ENTERO = 0) AND (CENTIMOS = 0))) THEN
      SET EN_LETRAS = CONCAT(EN_LETRAS, NUMERO_MENOR_MIL(CENTENAS));
   END IF;
   IF (CENTIMOS > 0) THEN
      IF (CENTIMOS = 1) THEN
         SET  AUX = 'CÉNTIMO';
      ELSE
         SET AUX = 'CÉNTIMOS';
      END IF;
   END IF;
   IF (ENTERO > 0) THEN
     SET CENTIMO_AUX = NUMERO_MENOR_MIL(CENTIMOS);
     SET CENTIMO_AUX = REPLACE(CENTIMO_AUX,'UNO ','UN ');
      SET EN_LETRAS = CONCAT(EN_LETRAS, 'CON ', CENTIMO_AUX , AUX);
   ELSE
      SET EN_LETRAS = CONCAT(EN_LETRAS, CENTIMO_AUX, AUX);
   END IF;
   RETURN(EN_LETRAS);
END; //
alejandro.laord
 
Mensajes: 1
Registrado: Dom Sep 22, 2019 8:20 pm


Volver a SGBD Oracle

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 15 invitados