jueves, 8 de enero de 2009

Convertir numeros a letras usando pl/sql

Convertir numeros a letras

Oracle PL/SQL: Como convertir un número a letras.

Oracle PL/SQL: Pasar número a letras en español , castellano o catalán..

Oracle PL/SQL: Expresar un numero con letras.

Oracle PL/SQL: Convertir una fecha a literal o letras.

Oracle PL/SQL: Usar NLS_DATE_LANGUAGE en to_char.

SITUACIÓN:

Podemos encontrarnos (los clientes que a veces son muy caprichosos...) con que una fecha tipo 11/09/1714 queremos expresarla como "once de septiembre de mil novecientos catorce" y si se nos pide en ingles podemos usar

select to_char (to_date ('11/09/1714','DD/MM/RRRR'),'day month year') from dual;

que nos devuelve:

"tuesday september seventeen fourteen"

por lo que el día ya no nos lo transforma tal cual en letras si no en el día de la semana, el mes funciona bien y el año... bueno yo no se mucho ingles pero diria que no es la mejor traducción no... y en castellano o catalán? pues se puede modificar la sessión o user la select así:

select to_char (to_date ('11/09/1714','DD/MM/RRRR'),'day month year','NLS_DATE_LANGUAGE=CATALAN') from dual;
select to_char (to_date ('11/09/1714','DD/MM/RRRR'),'day month year','NLS_DATE_LANGUAGE=SPANISH') from dual;

que nos devuelven respectivamente:
"dimarts setembre seventeen fourteen"
"martes septiembre seventeen fourteen"

por lo que si que nos traduce el día (pero no el numero si no el día de la semana, como antes) , el mes y... y el año? que le pasa?

EXPLICACIÓN:

Una vez más... cosas raras del oracle mira...

Como esta solución no nos convence tendremos que usar otra y que además nos servirá para convertir cualquier número y no solo fechas (que no dejan de ser una agrupación de números)

SOLUCIÓN:

En el caso de querer convertir un número a letras en inglés lo tenemos bastante fácil haciendo una trampita y pasandolo a fecha juliana con la limitaci'on de que no acepta n'umeros superiores a 7 cifras.

select to_char(to_date('1234567','J'),'Jsp') from dual;

que nos devuelve
"One Million Two Hundred Thirty-Four Thousand Five Hundred Sixty-Seven"

Y en catalán o castellano?

Pues he cogido de internet una función bastante simple pero larga y pesada de hacer y la he traducido también al catalán (aquí trabajamos en catalán xD) y añadido un parámetro.

------------------------------------------------------------------------------------------------------------
----- Converteix una xifra numérica a l'equivalent en text.
----- Parametres: IMP -> l'import en format XXXXXX.XX
----- NUMDEC -> indica la quantitat de numeros que hi ha com a decimals (maxim i per defecte 2)
----- IDIOMA -> CATalà o ESP Castellà
------------------------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION Numero_a_Texto ( Imp Number, NumDec Number Default 2, idioma varchar2 default 'CAT' )

RETURN VarChar2
IS
Es_Un_Numero Number;
imp_let VarChar2(150);
imp_char VarChar2(12);
impd_char VarChar2(2);
importe_let varchar2(100);

BEGIN
-- Se pasa a cadena
imp_char := To_Char(Trunc(Imp));
impd_char:= Substr(Ltrim(Ltrim(To_Char(Imp - Trunc(Imp)),'.'),','), 1, NumDec);

if idioma = 'ESP' then
SELECT

--Centenas de miles de millones.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),1,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,2),'00','CIEN ','CIENTO '),
2,'DOSCIENTAS ',
3,'TRESCIENTAS ',
4,'CUATROCIENTAS ',
5,'QUINIENTAS ',
6,'SEISCIENTAS ',
7,'SETECIENTAS ',
8,'OCHOCIENTAS ',
9,'NOVECIENTAS ',
0,'')

||
--Decenas miles de millones.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),2,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1),
0,'DIEZ ',
1,'ONCE MIL ',
2,'DOCE MIL ',
3,'TRECE MIL ',
4,'CATORCE MIL ',
5,'QUINCE MIL ',
6,'DICISEIS MIL ',
7,'DIECISIETE MIL ',
8,'DIECIOCHO MIL ',
9,'DIECINUEVE MIL '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'VEINTE ','VEINTI'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'TREINTA ','TREINTA Y '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'CUARENTA ','CUARENTA Y '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'CINCUENTA ','CINCUENTA Y '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'SESENTA ','SESENTA Y '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'SETENTA ','SETENTA Y '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'OCHENTA ','OCHENTA Y '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'NOVENTA ','NOVENTA Y '),
0,'')

||
--Unidades de milles de millones
DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,3),'001','MIL ','UN MIL ' ) ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','DOS MIL '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','TRES MIL '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','CUATRO MIL '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','CINCO MIL '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','SEIS MIL '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','SIETE MIL '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','OCHO MIL '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','NUEVE MIL '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,3),'000','','MIL '))

||
--Centenas de millon.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),4,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,2),'00','CIEN ','CIENTO '),
2,'DOSCIENTAS ',
3,'TRESCIENTAS ',
4,'CUATROCIENTAS ',
5,'QUINIENTAS ',
6,'SEISCIENTAS ',
7,'SETECIENTAS ',
8,'OCHOCIENTAS ',
9,'NOVECIENTAS ',
0,'')

||
--Decenas de millon.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),5,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1),
0,'DIEZ ',
1,'ONCE MILLONES ',
2,'DOCE MILLONES ',
3,'TRECE MILLONES ',
4,'CATORCE MILLONES ',
5,'QUINCE MILLONES ',
6,'DICISEIS MILLONES ',
7,'DIECISIETE MILLONES ',
8,'DIECIOCHO MILLONES ',
9,'DIECINUEVE MILLONES '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'VEINTE ','VEINTI'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'TREINTA ','TREINTA Y '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'CUARENTA ','CUARENTA Y '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'CINCUENTA ','CINCUENTA Y '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'SESENTA ','SESENTA Y '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'SETENTA ','SETENTA Y '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'OCHENTA ','OCHENTA Y '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'NOVENTA ','NOVENTA Y '),
0,'')

||
--Unidades de millon.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),3,2),'00','UN MILLON ','UN MILLONES ') ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','DOS MILLONES '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','TRES MILLONES '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','CUATRO MILLONES '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','CINCO MILLONES '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','SEIS MILLONES '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','SIETE MILLONES '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','OCHO MILLONES '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','NUEVE MILLONES '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),3,3),'000','','MILLONES '))

||
--Centenas de millar.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),7,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,2),'00','CIEN ','CIENTO '),
2,'DOSCIENTAS ',
3,'TRESCIENTAS ',
4,'CUATROCIENTAS ',
5,'QUINIENTAS ',
6,'SEISCIENTAS ',
7,'SETECIENTAS ',
8,'OCHOCIENTAS ',
9,'NOVECIENTAS ',
0,'')

||
--Decenas de millar.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),8,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1),
0,'DIEZ ',
1,'ONCE MIL ',
2,'DOCE MIL ',
3,'TRECE MIL ',
4,'CATORCE MIL ',
5,'QUINCE MIL ',
6,'DICISEIS MIL ',
7,'DIECISIETE MIL ',
8,'DIECIOCHO MIL ',
9,'DIECINUEVE MIL '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'VEINTE ','VEINTI'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'TREINTA ','TREINTA Y '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'CUARENTA ','CUARENTA Y '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'CINCUENTA ','CINCUENTA Y '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'SESENTA ','SESENTA Y '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'SETENTA ','SETENTA Y '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'OCHENTA ','OCHENTA Y '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'NOVENTA ','NOVENTA Y '),
0,'')

||
--Unidades de millar
DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),7,3),'001','MIL ','UN MIL ' ) ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','DOS MIL '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','TRES MIL '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','CUATRO MIL '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','CINCO MIL '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','SEIS MIL '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','SIETE MIL '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','OCHO MIL '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','NUEVE MIL '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),7,3),'000','','MIL '))

||
--Centenas.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),10,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,2),'00','CIEN','CIENTO '),
2,'DOSCIENTAS ',
3,'TRESCIENTAS ',
4,'CUATROCIENTAS ',
5,'QUINIENTAS ',
6,'SEISCIENTAS ',
7,'SETECIENTAS ',
8,'OCHOCIENTAS ',
9,'NOVECIENTAS ',
0,'')

||
--Decenas.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),11,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12),
0,'DIEZ ',
1,'ONCE ',
2,'DOCE ',
3,'TRECE ',
4,'CATORCE ',
5,'QUINCE ',
6,'DICISEIS ',
7,'DIECISIETE ',
8,'DIECIOCHO ',
9,'DIECINUEVE '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'VEINTE ','VEINTI'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'TREINTA ','TREINTA Y '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'CUARENTA ','CUARENTA Y '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'CINCUENTA ','CINCUENTA Y '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'SESENTA ','SESENTA Y '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'SETENTA ','SETENTA Y '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'OCHENTA ','OCHENTA Y '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'NOVENTA ','NOVENTA Y '),
0,'')

||
--Unidades.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),12,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','UN '),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','DOS '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','TRES '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','CUATRO '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','CINCO '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','SEIS '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','SIETE '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','OCHO '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','NUEVE '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,12),'000000000000','CERO ','') )
||
DECODE(LPAD(impd_char,2,'0'),'00','','CON ')||
--Decimales
--Decenas.
DECODE (SUBSTR(LPAD(impd_char,2,'0'),1,1),
0,DECODE(SUBSTR(LPAD(impd_char,2,'0'),2),
1,'UNO ',
2,'DOS ',
3,'TRES ',
4,'CUATRO ',
5,'CINCO ',
6,'SEIS ',
7,'SIETE ',
8,'OCHO ',
9,'NUEVE '),
1,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2),
0,'DIEZ ',
1,'ONCE ',
2,'DOCE ',
3,'TRECE ',
4,'CATORCE ',
5,'QUINCE ',
6,'DICISEIS ',
7,'DIECISIETE ',
8,'DIECIOCHO ',
9,'DIECINUEVE '),
2,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'VEINTE ','VEINTI'),
3,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'TREINTA ','TREINTA Y '),
4,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'CUARENTA ','CUARENTA Y '),
5,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'CINCUENTA ','CINCUENTA Y '),
6,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'SESENTA ','SESENTA Y '),
7,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'SETENTA ','SETENTA Y '),
8,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'OCHENTA ','OCHENTA Y '),
9,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'NOVENTA ','NOVENTA Y '),
0,'')
||
--Unidades.
DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),0,'',
DECODE (SUBSTR(LPAD(impd_char,2,'0'),2,1),
1,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','UN '),
2,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','DOS '),
3,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','TRES '),
4,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','CUATRO '),
5,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','CINCO '),
6,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','SEIS '),
7,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','SIETE '),
8,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','OCHO '),
9,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','NUEVE ')))
INTO importe_let
FROM DUAL;

elsif idioma = 'CAT' then
SELECT

--Centenes de milers de milions.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),1,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,2),'00','CENT ','CENT '),
2,'DOSCENTS ',
3,'TRESCENTS ',
4,'QUATRECENTS ',
5,'CINCENTS ',
6,'SISCENTS ',
7,'SETCENTS ',
8,'VUITCENTS ',
9,'NOUCENTS ',
0,'')

||
--Desenes milers de milions.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),2,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1),
0,'DEU ',
1,'ONZE MIL ',
2,'DOTZE MIL ',
3,'TRETZE MIL ',
4,'CATORZE MIL ',
5,'QUINZE MIL ',
6,'SETZE MIL ',
7,'DISSET MIL ',
8,'DIVUIT MIL ',
9,'DINOU MIL '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'VINT ','VINT-I-'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'TRENTA ','TREINTA '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'QUARANTA ','QUARANTA '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'CINQUANTA ','CINQUANTA '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'SEIXANTA ','SEIXANTA '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'SETANTA ','SETANTA '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'VUITANTA ','VUITANTA '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1), 0,'NORANTA ','NORANTA '),
0,'')

||
--Unitats de milers de milions
DECODE (SUBSTR(LPAD(imp_char,12,'0'),3,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,3),'001','MIL ','UN MIL ' ) ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','DOS MIL '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','TRES MIL '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','QUATRE MIL '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','CINC MIL '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','SIS MIL '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','SET MIL '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','VUIT MIL '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),2,1),1,'','NOU MIL '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,3),'000','','MIL '))

||
--Centenes de milió
DECODE (SUBSTR(LPAD(imp_char,12,'0'),4,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,2),'00','CENT ','CENT '),
2,'DOS-CENTS ',
3,'TRES-CENTS ',
4,'CUATRE-CENTS ',
5,'CINC-CENTS ',
6,'SIS-CENTS ',
7,'SET-CENTS ',
8,'VUIT-CENTS ',
9,'NOU-CENTS ',
0,'')

||
--Desenes de milió (m'entra complexe d'assafata del cuponazo)
DECODE (SUBSTR(LPAD(imp_char,12,'0'),5,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1),
0,'DEU ',
1,'ONZE MILIONS ',
2,'DOTZE MILIONS ',
3,'TRETZE MILIONS ',
4,'CATORZE MILIONS ',
5,'QUINZE MILIONS ',
6,'SETZE MILIONS ',
7,'DISSET MILIONS ',
8,'DIVUIT MILIONS ',
9,'DINOU MILIONS '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'VINT ','VINT-I-'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'TRENTA ','TRENTA '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'QUARANTA ','QUARANTA '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'CINQUANTA ','CINQUANTA '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'SEIXANTA ','SEIXANTA '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'SETANTA ','SETANTA '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'VUITANTA ','VUITANTA '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1), 0,'NORANTA ','NORANTA '),
0,'')

||
--Unitats de milió
DECODE (SUBSTR(LPAD(imp_char,12,'0'),6,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),3,2),'00','UN MILIÓ ','UN MILIONS ') ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','DOS MILIONS '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','TRES MILIONS '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','QUATRE MILIONS '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','CINC MILIONS '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','SIS MILIONS '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','SET MILIONS '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','VUIT MILIONS '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),5,1),1,'','NOU MILIONS '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),3,3),'000','','MILIONS '))

||
--Centenes de millar
DECODE (SUBSTR(LPAD(imp_char,12,'0'),7,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,2),'00','CENT ','CENT '),
2,'DOS-CENTS ',
3,'TRES-CENTS ',
4,'CUATRE-CENTS ',
5,'CINC-CENTS ',
6,'SIS-CENTS ',
7,'SET-CENTS ',
8,'VUIT-CENTS ',
9,'NOU-CENTS ',
0,'')

||
--Desenes de millar
DECODE (SUBSTR(LPAD(imp_char,12,'0'),8,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1),
0,'DEU ',
1,'ONZE MIL ',
2,'DOTZE MIL ',
3,'TRETZE MIL ',
4,'CATORZE MIL ',
5,'QUINZE MIL ',
6,'SETZE MIL ',
7,'DISSET MIL ',
8,'DIVUIT MIL ',
9,'DINOU MIL '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'VINT ','VINT-I-'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'TRENTA ','TRENTA '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'QUARANTA ','QUARANTA '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'CINQUANTA ','CINQUANTA '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'SEIXANTA ','SEIXANTA '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'SETANTA ','SETANTA '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'VUITANTA ','VUITANTA '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1), 0,'NORANTA ','NORANTA '),
0,'')

||
--Unitats de millar
DECODE (SUBSTR(LPAD(imp_char,12,'0'),9,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),'1','',
DECODE(SUBSTR(LPAD(imp_char,12,'0'),7,3),'001','MIL ','UN MIL ' ) ),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','DOS MIL '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','TRES MIL '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','QUATRE MIL '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','CINC MIL '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','SIS MIL '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','SET MIL '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','VUIT MIL '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),8,1),1,'','NOU MIL '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),7,3),'000','','MIL '))

||
--Centenes
DECODE (SUBSTR(LPAD(imp_char,12,'0'),10,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,2),'00','CENT','CENT '),
2,'DOS-CENTS ',
3,'TRES-CENTS ',
4,'CUATRE-CENTS ',
5,'CINC-CENTS ',
6,'SIS-CENTS ',
7,'SET-CENTS ',
8,'VUIT-CENTS ',
9,'NOU-CENTS ',
0,'')

||
--Desenes
DECODE (SUBSTR(LPAD(imp_char,12,'0'),11,1),
1,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12),
0,'DEU ',
1,'ONZE ',
2,'DOTZE ',
3,'TRETZE ',
4,'CATORZE ',
5,'QUINZE ',
6,'SETZE ',
7,'DISSET ',
8,'DIVUIT ',
9,'DINOU '),
2,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'VINT ','VINT-I-'),
3,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'TRENTA ','TRENTA '),
4,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'QUARANTA ','QUARANTA '),
5,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'CINQUANTA ','CINQUANTA '),
6,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'SEIXANTA ','SEIXANTA '),
7,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'SETANTA ','SETANTA '),
8,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'VUITANTA ','VUITANTA '),
9,DECODE (SUBSTR(LPAD(imp_char,12,'0'),12), 0,'NORANTA ','NORANTA '),
0,'')

||
--Unitats.
DECODE (SUBSTR(LPAD(imp_char,12,'0'),12,1),
1,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','UN '),
2,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','DOS '),
3,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','TRES '),
4,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','QUATRE '),
5,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','CINC '),
6,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','SIS '),
7,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','SET '),
8,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','VUIT '),
9,DECODE(SUBSTR(LPAD(imp_char,12,'0'),11,1),1,'','NOU '),
0,DECODE(SUBSTR(LPAD(imp_char,12,'0'),1,12),'000000000000','ZERO ','') )
||
DECODE(LPAD(impd_char,2,'0'),'00','','AMB ')||
--Decimals
--Desenes.
DECODE (SUBSTR(LPAD(impd_char,2,'0'),1,1),
0,DECODE(SUBSTR(LPAD(impd_char,2,'0'),2),
1,'UN ',
2,'DOS ',
3,'TRES ',
4,'QUATRE ',
5,'CINC ',
6,'SIS ',
7,'SET ',
8,'VUIT ',
9,'NOU '),
1,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2),
0,'DEU ',
1,'ONZE ',
2,'DOTZE ',
3,'TRETZE ',
4,'CATORZE ',
5,'QUINZE ',
6,'SETZE ',
7,'DISSET ',
8,'DIVUIT ',
9,'DINOU '),
2,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'VINT ','VINT-I-'),
3,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'TRENTA ','TRENTA '),
4,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'QUARANTA ','QUARANTA '),
5,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'CINQUANTA ','CINQUANTA '),
6,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'SEIXANTA ','SEIXANTA '),
7,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'SETANTA ','SETANTA '),
8,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'VUITANTA ','VUITANTA '),
9,DECODE (SUBSTR(LPAD(impd_char,2,'0'),2), 0,'NORANTA ','NORANTA '),
0,'')
||
--Unitats.
DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),0,'',
DECODE (SUBSTR(LPAD(impd_char,2,'0'),2,1),
1,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','UN '),
2,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','DOS '),
3,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','TRES '),
4,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','QUATRE '),
5,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','CINC '),
6,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','SIS '),
7,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','SET '),
8,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','VUIT '),
9,DECODE(SUBSTR(LPAD(impd_char,2,'0'),1,1),1,'','NOU ')))
INTO importe_let
FROM DUAL;
end if;

RETURN (importe_let);

END Numero_a_Texto;


Luego usando esta función he creado otra pequeñita que directamente nos pasa una fecha determinada a su descripción en letras.

create or replace function data_a_text(data in date, idioma in varchar2) return varchar2 is
Result varchar2(200);
begin
if idioma = 'CAT' then
select lower(numero_a_texto (to_char (data,'dd'),2, 'CAT') || 'de ' ||
trim(to_char (data,'month','NLS_DATE_LANGUAGE=CATALAN')) || ' de ' ||
numero_a_texto (to_char (data,'rrrr'),2, 'CAT')) into result from dual;
elsif idioma = 'ESP' then
select lower(numero_a_texto (to_char (data,'dd'),2, 'ESP') || 'de ' ||
trim(to_char (data,'month','NLS_DATE_LANGUAGE=SPANISH')) || ' de ' ||
numero_a_texto (to_char (data,'rrrr'),2, 'ESP')) into result from dual;
end if;
return(Result);
end data_a_text;

Espero que os sean útiles :P

jueves, 9 de octubre de 2008

go_block no permitido en los triggers POST

Oracle forms: No me deja hacer go_block

Oracle forms: Como puedo ejecutar una consulta (execute_query) de un bloque de datos cuando cambio el valor de un item en otro bloque de datos?

Oracle forms: execute_query de otro bloque en trigger post-block

Oracle forms: no permite hacer go_block execute_query en el post-block

SITUACIÓN:
El otro día me volví a encontrar con un problema parecido. Tengo dos tablas, una con los elementos de un menú y otra con la composición del menú. En la composición tengo un identificador de elemento que es el padre y otro que es el hijo, uno que indica el orden y otro el nivel de menú. Yo quería mostrar en un bloque los padres y en otro los hijos del padre que seleccionemos. La cosa parece clara... los hijos son aquellos elementos que en la table composicion tienen como padre el elemento del bloque padre pero... Como puedo hacer una relación a través de una tabla externa? No puedo... oracle forms no me deja.

Lo primero que uno piensa es en hacer un go_block ('hijos'); execute_query; en el trigger post-block o post-query del padre pero... forms no nos deja. ¿Que hacemos?

EXPLICACIÓN:

A Oracle forms a saber porque motivo de diseño no le da la gana permitir facilidades así. Esperemos que en la próxima y no muy anunciada versión de Oracle forms 11 lo arreglen pero de momento...


SOLUCIÓN:

La solución es poner el go_block ('hijos'); execute_query; en el trigger WHEN-NEW-ITEM-INSTANCE del bloque padre asi cuando se valide cualquier cosa del bloque padre nos ejecutará la query en el hijo. Esto no nos crea ninguna relación padre hijo que haga comprobaciones de integridad o que nos borre en cascada y debemos ser nosotros quien lo programemos pero nos permite salir del apuro.

Puede , segun la situación que esta solución nos meta en un bucle sin salida por lo que os remito a mi otro post parecido donde cuento como saber el elemento actual para filtrar el trigger y arreglar el problema del execute query en el post-block de oracle forms

Si lees este post u otros y te sirve de ayuda dejame un comentario porque ya no se si esto sirve a alguien o escribo para llenar de bytes internet. Grácias :P



lunes, 15 de septiembre de 2008

Oracle Reports: No funciona Order by con parámetro

Oracle Reports: No funciona Order by con parámetro
Oracle Reports: No funciona ordenar pasando el valor por parámetro
Oracle Reports: Me ignora el order by dinámico
Oracle Reports: Como poner un order by dinámico

Situación:
Tenemos un report con una consulta normal sobre una base de datos y queremos poder ordenar el resultado según un parámetro que nos indica por que columna queremos ordenar. Si no fuera dinámico simplemente lo añadimos normal a la consulta pero si es dinámico la primera opción que pensamos es poner un "orden by :parametro_orden" pero sin saber muy bien porque es algo que a veces va y a veces no. Si el parámetro además no nos indica la columna literalmente o la posición si no otro valor no relacionado pues debemos hacer un decode pero si las columnas son de diferente tipo (numérico y carácter por ejemplo) el que pongamos como segunda parte del decode nos fallará. ¿Como lo hacemos pues?

Explicación:
En el caso de no necesitar el decode no entiendo porque a veces no va, debe ser un error más de reports.
En el caso del decode si falla puede ser por lo anterior o porque son de diferentes tipos y se hace un lio.

Solución:
No se si era la idea original o un parche que han pensado algunos y se ha vuelto una especie de estandar pero ahora mismo es lo único que me funciona sin problemas.

En primer lugar creamos una funcion que nos devuelva, segun el valor del parámetro orden, la cadena de order by:




En segundo lugar a la consulta cambiamos el order by por &nombre_de_la_funcion.



Y ya funciona :P

viernes, 5 de septiembre de 2008

Oracle forms: Cambiar atributo de un elemento del registro actual y no de todos.

Oracle forms: Cambiar atributo de un elemento del registro actual y no de todos.

Oracle forms: Cambiar atributo solo del registro actual.

Oracle forms: Cambiar visualmente un atributo y no todos los del bloque.

 

 

Situación:

Tenemos un bloque de datos del que visualizamos más de un registro a la vez (el típico listado) y queremos cambiar el valor de fondo del campo nombre en aquellos en que esté vacío. El problema es que si usamos el

 

set_item_property ('GENTE_FEA.NOMBRE',BACKGROUND_COLOR, 'r100g100b255');

 

El color se aplicará al campo nombre de todos los registros de ese bloque y solo me interesa que afecte a los vacios.

 

Explicación:

En estos casos nos molesta pero para otros (por ejemplo: no dejar poner nombres en este bloque hasta que el DNI del jefe este completo) nos sirve así que hay que utilizar otro método.

 

Solución:

Crearemos un registro visual con el color que nos interesa y luego en el trigger que utilicemos para determinar si poner o no el color al campo nombre en función de si es o no nulo cambiamos el

 

set_item_property ('GENTE_FEA.NOMBRE',BACKGROUND_COLOR, 'r100g100b255');

 

Por

 

display_item('GENTE_FEA.NOMBRE'','atr_fondo_azulao');

 

Y el cambio solo afectará al item NOMBRE del bloque GENTE_FEA del registro actual y no todos.

  

 

 

 

lunes, 28 de julio de 2008

Oracle Forms: FRM-41380: Cannot set the blocks query data source

Oracle Forms: FRM-41380: Cannot set the blocks query data source
Oracle Forms: set_block_property QUERY_DATA_SOURCE_NAME error
Oracle Forms: definir tabla de un bloque de datos
Oracle Forms: Error FRM-41380

Situación:
Tenemos un bloque de datos que lee de base de datos pero no de una tabla si no de una consulta (Query data source type = from clause query) y queremos poder redefinir este origen en función de otros parametros pero cuando lo hacemos mediante

set_block_property ('bloque de datos',QUERY_DATA_SOURCE_NAME , cadena_from);

solo nos funciona la primera vez y luego nos devuelve "FRM-41380: Cannot set the blocks query data source".

Explicación:
Otra de las tonterías de forms que nos obliga a hacer un paso previo.

Solución:
Ya lo hacemos correctamente pero antes de definir el nuevo origen hay que vaciar el bloque de datos para que tenga el estado "new".
Para hacerlo tenemos el ya mítico

go_block ('bloque_de_datos');
clear_block (no_validate);

martes, 8 de julio de 2008

Como saber el elemento actual cuando aprieto un botón

"Oracle forms" Como saber el elemento actual cuando aprieto un botón
"Oracle forms" Como puedo saber el elemento anterior

Situación:
Tenemos dos bloques de datos origen destino por ejemplo y nos interesa que al apretar un botón los datos del item actual del bloque origen pase al elemento correspondiente del bloque destino. ¿Como podemos saber que elemento es?

Explicación:
La respuesta lógica sería :system.current_item pero eso nos devuelve que el elemento actual es el botón que apretamos para pasar el campo. Entonces ¿como puedo saber cual es el anterior? Podríamos guardar en una variable el valor del último elemento mediante triggers pero eso además de laborioso es en la mayoría de casos absurdo.

Solución:
En las propiedades del boton tenemos que poner que no sea navegable ni con el ratón ni con el teclado. Así pues como no hemos ido al elemento, aunque podamos hacer click, “oracle forms” tendrá como :system.current_item el elemento anterior a presionar el botón. Así de simple :)

miércoles, 2 de julio de 2008

Mandar correo desde oracle forms 9

Oracle forms: Mandar correo con outlook o firebird
Oracle forms: Abrir correo para mandar con outlook o firebird
Oracle forms: Como puedo mandar un correo desde oracle forms
Oracle forms: No me funciona OLE2 para mandar correo

Situación:

Queremos abrir una ventana del Outlook o Firebird o el gestor de correo que tengamos instalado y usando el objeto OLE2 del Outlook me da un error que no es de oracle.

Explicación:

En google encontrareis un código para mandar correos desde forms basado en OLE2 y aunque eso funciona bien con Oracle forms 6i no lo hace con Oracle forms 9 porque se considera el OLE2 como obsoleto.
Oracle Forms 9 se basa en web así que la solución lógica es intentar mandarlo como si de HTML usando “mailto:direccion”

Solución:

Para mandarlo así solo hay que pasarlo como dirección web y el navegador ya se encarga de abrir un nuevo correo de tu gestor de correo.

Para solo tenemos que poner
web.show_document('mailto:direccion@dominio.com’,'_blank');



(la captura es del outlook si… aunque no lo recomiendo por su baja seguridad sobretodo frente a virus si el cliente quiere outlook pues outlook para el cliente… xD)

Que versión de Oracle Forms usas?