Muchas veces cuando se esta programando una solución informática surge la necesidad de expresar números en letras, como por ejemplo al presentar el concepto de una factura, de un cheque o sencillamente leer números en formato literal.
Con el fin de hacer un poco más fácil esta tarea, les dejo el siguiente código en Oracle, el mismo es un procedimiento que convierte un número de entrada en letras. Puede ser modificarlo a su antojo y adaptado a sus necesidades.
Espero que sea de utilidad a más de uno...
1 /****************************************************************************/ 2 --PROCESAMIENTO QUE AL PASARLE UN NUMERO COMO PARÁMETRO LO CONVIERTE EN LETRAS 3 /****************************************************************************/ 4 PROCEDURE PR_NUMEROS_A_LETRAS( 5 numero in number 6 )IS 7 ----------------------------------------------- 8 --Declaracion de matrices-- 9 ----------------------------------------------- 10 TYPE LECTURA_UNIDADES IS VARRAY(200) OF VARCHAR2(50); 11 TYPE LECTURA_DECENAS IS VARRAY(200) OF VARCHAR2(50); 12 TYPE LECTURA_CENTENAS IS VARRAY(200) OF VARCHAR2(50); 13 TYPE LECTURA_MILLARES IS VARRAY(200) OF VARCHAR2(50); 14 ----------------------------------------------- 15 --matriz para las unidades hasta el 19-- 16 ----------------------------------------------- 17 M_Unidades LECTURA_UNIDADES := LECTURA_UNIDADES( 18 'UNO ' ,'DOS ' ,'TRES ' 19 ,'CUATRO ' ,'CINCO ' ,'SEIS ' 20 ,'SIETE ' ,'OCHO ' ,'NUEVE ' 21 ,'DIEZ ' ,'ONCE ' ,'DOCE ' 22 ,'TRECE ' ,'CATORCE ' ,'QUINCE ' 23 ,'DIECISÉIS ','DIECISIETE ' 24 ,'DIECIOCHO ','DIECINUEVE ' 25 ); 26 ----------------------------------------------- 27 --matriz para las decenas-- 28 ----------------------------------------------- 29 M_Decenas LECTURA_DECENAS := LECTURA_DECENAS( 30 'VEINTE ' ,'VEINTI' ,'TREINTA ' 31 ,'CUARENTA ' ,'CINCUENTA ' 32 ,'SESENTA ' ,'SETENTA ' 33 ,'OCHENTA ' ,'NOVENTA ' 34 ); 35 ----------------------------------------------- 36 --matriz para las centenas-- 37 ----------------------------------------------- 38 M_Centenas LECTURA_CENTENAS := LECTURA_CENTENAS( 39 'CIENTO ' ,'DOSCIENTOS ' ,'TRESCIENTOS ' 40 ,'CUATROCIENTOS ' ,'QUINIENTOS ' 41 ,'SEISCIENTOS ' ,'SETECIENTOS ' 42 ,'OCHOCIENTOS ' ,'NOVECIENT0S ' 43 ); 44 ----------------------------------------------- 45 --Declaración de variables-- 46 ----------------------------------------------- 47 millares varchar (50); 48 letCentenas varchar2(50); 49 letDecenas varchar2(50); 50 letUnidades varchar2(50); 51 texto varchar2(200); 52 numeroAuxiliar varchar2(100); 53 longitud_numero numeric; 54 letras varchar2(200); 55 grupo varchar2(3); 56 cantGrupo numeric(1); 57 decimales varchar2(200); 58 enTexto varchar2(20); 59 digitoDecena numeric; 60 digitoUnidad numeric;
61 BEGIN 62 ----------------------------------------------- 63 --Inicialización de variables-- 64 ----------------------------------------------- 65 cantGrupo := 0; 66 letras := ''; 67 texto := ''; 68 enTexto:=LTRIM(RTRIM(TO_CHAR(TRUNC(Numero), '999999999999'))); 69 enTexto:= LPAD(enTexto,12,'0'); 70 longitud_numero:=LENGTH(enTexto);--obtengo la longitud del numero 71 --controla que el numero sea menor o igual de 12 posiciones y mayor que cero. 72 IF (longitud_numero = 12) AND (numero = 0) THEN 73 ----------------------------------------------- 74 --divide el numero en cuatro grupos de tres digitos-- 75 ----------------------------------------------- 76 FOR I IN 1..TO_NUMBER(longitud_numero)/3 LOOP 77 --inicializo ciertas variables cada vez que inicia un nuevo ciclo 78 letUnidades:=''; 79 letDecenas:=''; 80 letCentenas:=''; 81 millares:=''; 82 grupo:= SUBSTR(enTexto,I*3-2,3); --Divido en grupos de tres dígito 83 --obtenemos un numero auxiliar del grupo 84 numeroAuxiliar := TO_NUMBER(TO_CHAR(TRUNC(grupo),'999')); 85 cantGrupo := cantGrupo+1; --controlamos la cantidad del grupo 86 digitoDecena := TO_NUMBER(SUBSTR(TO_CHAR(grupo),2,2));--obtengo la decena 87 digitoUnidad := TO_NUMBER(SUBSTR(TO_CHAR(grupo),3,1));--obtengo la unidad 88 ----------------------------------------------------- 89 --SI SON CENTENAS EXTRAIGO EL VALOR DE LA CENTENA--- 90 ---------------------------------------------------- 91 IF LENGTH(TO_CHAR(numeroAuxiliar))=3 AND (TO_NUMBER(numeroAuxiliar)<> 0) THEN 92 IF (numeroAuxiliar = 100) THEN 93 letras:='CIEN '; 94 ELSE 95 letras := M_Centenas(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))); 96 END IF; 97 letCentenas := letras; 98 numeroAuxiliar := TO_NUMBER(substr(to_char(numeroAuxiliar), 2, 2)); 99 ND IF; 100 ----------------------------------------------------- 101 --SI SON DECENAS EXTRAIGO EL VALOR DE LA DECENA------ 102 ----------------------------------------------------- 103 --obtengo el dígito de la unidad 104 digitoUnidad := TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),2,1)); 105 IF(TO_NUMBER(numeroAuxiliar)<> 0) THEN--si el numero no es cero 106 IF (numeroAuxiliar >= 20) THEN--si el valor es mayor o igual 20 107 --si el numero es igual a 20 asigna el valor de 20 en la matriz decena. 108 IF (numeroAuxiliar = 20) THEN 109 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))-1); 110 letDecenas:= letras; 111 ELSE 112 --si el número esta menor o igual a 29 obtiene la descripción de la
--decena y le asgina el valor a letras 113 IF (numeroAuxiliar <= 29) THEN 114 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))); 115 letDecenas:= letras; 116 numeroAuxiliar:= TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),2,3)); 117 ELSE 118 --si la unidad es diferente a cero la "y" entre el valor de la
--decena y la unidad 119 IF (digitoUnidad <> 0) THEN 120 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))); 121 letDecenas:= letras||'Y '; 122 numeroAuxiliar:= TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),2,3)); 123 ELSE 124 --si es cero imprime solo la decena. 125 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))); 126 letDecenas:= letras; 127 numeroAuxiliar:= TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),2,3)); 128 END IF; 129 END IF; 130 END IF; 131 END IF; 132 END IF; 133 ----------------------------------------------------- 134 --SI SON UNIDADES EXTRAIGO EL VALOR DE LA UNIDAD----- 135 ----------------------------------------------------- 136 IF (numeroAuxiliar <> 0) AND (numeroAuxiliar <= 19) THEN 137 IF LENGTH(TO_CHAR(numeroAuxiliar))=1 THEN 138 --Asigna la letra de la unidad al valor correspondiente. 139 letras:=M_Unidades(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,1))); 140 letUnidades:=letras; 141 END IF; 142 IF LENGTH(TO_CHAR(numeroAuxiliar))=2 THEN 143 --Asigna la letra de la unidad al valor correspondiente. 144 letras:= M_Unidades(TO_NUMBER(SUBSTR(TO_CHAR(numeroAuxiliar),1,2))); 145 letUnidades:=letras; 146 END IF; 147 END IF; 148 ----------------------------------------------- 149 --Controlando las unidades de mil y de millón-- 150 ----------------------------------------------- 151 IF (cantGrupo = 1) OR (cantGrupo = 3)THEN--si esta en el grupo 1
--o en el tres 152 millares := 'MIL';--imprime mil al final 153 IF (TO_NUMBER(GRUPO)= 1) THEN 154 letUnidades:='';-- no imprimo nada en las unidades 155 ELSE 156 IF(digitoUnidad=1)AND (digitoDecena <> 11)THEN 157 letUnidades:='UN ';--imprimo un en los casos indicados anteriormente 158 END IF; 159 END IF; 160 ELSE 161 --si el grupo es dos entonces son millones 162 IF (cantGrupo = 2) THEN 163 IF(TO_NUMBER(grupo) = 1) THEN 164 millares:='MILLÓN'; 165 letUnidades:='UN '; 166 ELSE 167 IF(digitoDecena <> 11)AND(digitoUnidad = 1) THEN 168 millares := 'MILLONES'; 169 letUnidades:='UN '; 170 ELSE 171 millares:='MILLONES'; 172 END IF; 173 END IF; 174 END IF; 175 END IF; 176 ----------------------------------------------------------------- 177 --Evaluando cuando el grupo sea cero y en caso de ser lo limpio-- 178 ----------------------------------------------------------------- 179 IF (cantGrupo = 1) THEN 180 IF (to_number(grupo) = 0) THEN 181 millares:=''; 182 END IF; 183 END IF; 184 IF (cantGrupo = 2) THEN 185 IF(to_number(grupo) = 0) THEN 186 letUnidades:=''; 187 IF (numero > 999999999) THEN 188 millares:=millares; 189 ELSE 190 millares:=''; 191 END IF; 192 END IF; 193 ELSE 194 IF(cantGrupo = 3) THEN 195 IF(to_number(grupo) = 0) THEN 196 millares:=''; 197 END IF; 198 END IF; 199 END IF; 200 --voy imprimiendo la lectura de cada grupo 201 letras:=letCentenas||letDecenas||letUnidades||millares;
--concateno la lectura a texto por cada ciclo for
202 texto:=texto||' '||letras;
203 END LOOP;--termina el ciclo 204 ----------------------------------------------------- 205 --------------EVALUANDO SI HA DECIMALES-------------- 206 ----------------------------------------------------- 207 --Sí el número truncado es igual al numero digitado, no hay decimales 208 IF TRUNC(Numero) = Numero THEN 209 decimales := ''; 210 ELSE--por lo demás 211 --obtenemos el decimal y los dígito del decimal 212 decimales := SUBSTR(TO_CHAR(Numero,'999999999999.99'),15,2); 213 digitoDecena := TO_NUMBER(SUBSTR(TO_CHAR(DECIMALES),1,1)); 214 digitoUnidad := TO_NUMBER(SUBSTR(TO_CHAR(DECIMALES),2,1)); 215 --evalua que sea mayor que 20 216 IF (decimales >=20 ) THEN 217 --si el número es igual a 20 asigna el valor de 20 en la matriz decena. 218 IF (TO_NUMBER(decimales) = 20) THEN 219 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(decimales),1,1))-1); 220 decimales:= letras; 221 ELSE 222 --Si es menor o igual a 29 asigna la decena mas la unidad 223 IF (TO_NUMBER(decimales) <= 29) THEN 224 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(decimales),1,1)))|| 225 M_Unidades(TO_NUMBER(SUBSTR(TO_CHAR(digitoUnidad),1,1))); 226 decimales:= letras; 227 ELSE 228 --si la unidad es distinta a cero concatena la decena más el
--conector "y" más la unidad 229 IF (digitoUnidad <> 0) THEN 230 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(decimales),1,1))); 231 decimales:= letras||'Y '||
M_Unidades(TO_NUMBER(SUBSTR(TO_CHAR(digitoUnidad),1,1))); 232 ELSE 233 --si es cero imprime solo la decena. 234 letras:= M_Decenas(TO_NUMBER(SUBSTR(TO_CHAR(decimales),1,1))); 235 decimales:= letras; 236 END IF; 237 END IF; 238 END IF; 239 ELSE 240 decimales := M_Unidades(TO_NUMBER(SUBSTR(TO_CHAR(decimales),1,2))); 241 END IF; 242 decimales := 'CON '||decimales||' /00'; 243 END IF; 244 -- Une los decimales al valor de devuelto 245 texto := texto || Decimales; 246 DBMS_OUTPUT.PUT_LINE(texto); 247 ELSE 248 DBMS_OUTPUT.PUT_LINE('NUMERO FUERA DE RANGO'); 249 END IF; 250 EXCEPTION 251 WHEN OTHERS THEN 252 dbms_output.put_line('IMPOSIBLE CONVERTIR EL NO.'||enTexto); 253 END PR_NUMEROS_A_LETRAS;
No hay comentarios:
Publicar un comentario