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)

viernes, 27 de junio de 2008

Oracle forms ¿cómo quito el mensaje de guardar? o cambiar estado del registro a QUERY

Oracle forms ¿cómo quito el mensaje de guardar?

Oracle forms Desactivar mensaje de guardar

Oracle forms Cuando cambio de bloque me pide guardar

Oracle forms Cuando cambio de bloque no quiero que me pida guardar

Oracle forms: cambiar estado del registro a no modificado

Oracle forms: cambiar estado del registro a QUERY


Situación:

Cuando en un bloque de datos vinculado a la BBDD hacemos un cambio directa o indirectamente y cambiamos de bloque, de registro o ciertas opciones más automáticamente nos sale un mensaje de Oracle forms en que nos pide si queremos o no guardar los cambios.




Explicación:

Muchas veces no nos interessa eso porque el bloque nos interesa que esté vinculado a la BBDD (base de datos) para hacer las selects con las ventajas del autofiltrado pero no queremos que sirva para guardar en BBDD. Lo lógico sería hacer que no se pueda hacer insert o update (insert/update allowed) pero entonces solo nos dejaría escribir en el bloque en caso de estar en modo enter-query y claro, para crear registros pues no nos sirve.


Solución:

Una primera solución es poner el nivel de alertas a 5 aunque no se porque en ciertas versiones y ciertos casos eso no elimina el error. Intentadla por si acaso:

:system.message_level := 5;

La otra solución consiste en crear una variable auxiliar que nos indique si ese registro se ha modificado o no y manualmente cambiar el estado del registro de modificado a no modificado para que oracle forms al hacer las comprobaciones crea que no hay ningun registro modificado y por lo tanto no pedirá guardar. Lo más fácil es hacer un triger de post-change a nivel de bloque y en el interior poner algo como


begin
--si el estado del registro no es ‘QUERY’ es que lo han modificado
if get_record_property (:system.cursor_record,'blk_personas',status) <> 'QUERY' then
-- guardo en mi variable para saber que si se ha modificado
:blk_personas.modificado:=1;
--le hago creer a forms que no devolviendole al estado QUERY
set_record_property(:system.cursor_record,'per',status,query_status);
end if;
end;


martes, 10 de junio de 2008

FRM-30187: El tamaño de la columna CHAR en el grupo de registros debe estar comprendido entre 1 y 2000.

FRM-30187: El tamaño de la columna CHAR en el grupo de registros debe estar comprendido entre 1 y 2000.
Grupo de registros LOVxxx
Pantalla: xxxxxx

Situación:

Creamos una lista de valores o la editamos y al compilar nos sale este error.

Explicación:

Cuando creamos o editamos a partir de una consulta (select) y esta contiene concatenaciones, llamadas a funciones o demás factores que impiden a Oracle Forms calcular la longitud del campo varchar2 nos pone por defecto 4000. Hay quien piensa que es un error de Oracle Forms porque no tiene sentido poner 4000 y que luego te diga que el máximo es 2000 y hay quien piensa que este error te lo pone para que lo redefinas tú manualmente.

Solución:

Sea como sea hay que ir al grupo de registros (record group) sobre el que va la Lista de valores (LOV) ( lo hayamos creado antes que la LOV o mediante el LOV wizzard o asistente de LOV) y en Column Specifications le damos para abrir el popup

Y vemos que en las columnas de tipo Character nos ha puesto de longitud (length) 4000 así que los redefinimos todos y guardamos. Ya podemos compilar bien ;P

Situación 2:

Comprobamos los campos como se indica arriba y aun así sale el error.

Explicación:

Cuando creamos el Record Group y la LOV a veces en la select ponemos más campos de los que realmente usamos y aunque no salgan luego cuando miramos las columnas y tal, allá están.

Solución:

Si realmente no los necesitamos los quitamos y si los necesitamos pues tenemos que hacerlos aparecer, aunque luego los ocultemos, para poder especificar una longitud inferior a los 4000.

lunes, 26 de mayo de 2008

Oracle forms: no me deja cambiar el color de fondo

Oracle forms: no me deja cambiar el color de fondo

Oracle forms: como puedo poner el color

Oracle forms: no me deja poner colores manualmente

SITUACIÓN:

(son 2 situaciones diferentes pero bastante relacionadas)

1) Intento cambiar el color de fondo de un canvas y solo me deja elegir entre la paleta que tiene mediante clic en el popup de colores que sale, mediante RGB pero no valores exadecimales si no porcentuales asi R100G50B0 significa 100% de rojo, 50% de verde y 0% de azul pero… solo nos lo deja poner si el color existe en la paleta al igual que si intentamos ponerlo como gray30 (gray 30%) o similares.

2) Otro problema es que inicialmente esta a pero si lo cambiamos en algunos elementos si nos deja volverlo a dejar como mediante la opción “no fill” que supongo que en castellano aparecerá como “sin relleno” “no llenar” o algo así.

EXPLICACIÓN:

1 Por defecto oracle forms viene con la opción de paleta de colores solo de lectura.

2 Forms tiene errores absurdos, a nadie debería extrañarle.

SOLUCIÓN:

1) Vamos a Edit > Preferences y cambiamos la opción “color mode” a Editable

Luego nos vamos a la parte visual y vamos a Edit > Layout Options > Color Palette y ya nos aparece la paleta y el botón de editar color tan típico del Paint brush.

2) En vez de intentar buscar el color editando la paleta o de intentar meter como valor el “blank” que nos sugiere la ayuda o el lo que hacemos es cambiar el “Visual Attribute group” a otro valor y luego lo volvemos a dejar en default y ala, los 3 valores a


viernes, 23 de mayo de 2008

No puedo hacer go_block 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

SITUACIÓN:

Es bastante típica, tenemos un elemento (item) en un bloque y queremos que cuando se modifique vaya a otro bloque y ejecute una consulta. El modo correcto de hacer esto cuando se trata de una relación padre-hijo (por ejemplo un bloque personas que cuando cambian la persona actualice el bloque de por ejemplo trabajos académicos de esta persona) es el de las relaciones uniendo los dos bloques por el identificador de la persona.

A veces sin embargo no es una relación así y se trata por ejemplo “si la persona es hombre carga el bloque de burradas y elimina el de tonterías y si la persona es mujer carga el bloque tonterías y elimina el de burradas” donde ya hay condiciones, algún que otro análisis de variables… y no nos es posible hacer la relación lo primero que uno piensa es “go_block (‘tonterías’); execute_query;” pero entonces nos sale que no es posible ejecutar go_block en el post-change ni varios otros a nivel de item.

EXPLICACIÓN:

A Oracle forms a saber porque motivo de diseño no le da la gana permitir facilidades así.

SOLUCIÓN:

La solución es ponerlo en el trigger WHEN-NEW-ITEM-INSTANCE del bloque donde tenemos el objeto que al cambiar active lo otro. Pero claro, eso nos pasaría con cualquiera de los elementos del bloque así que tenemos que filtrarlo poniendo en el trigger

if :system.current_item = 'nombre del elemento activador’ and (variable_auxiliar = 0 or variable_auxiliar is null) then

go_block (‘tonterias’);

execute_query;

variable_auxiliar:=1;

end if;

Lo de la variable auxiliar es para que no caiga en un bucle infinito y así controlamos que solo se hace una vez.


jueves, 22 de mayo de 2008

Error 0

Oracle forms: Error 0.


Muchas veces Oracle nos da errores negativos o uno muy curioso que dice, “error 0 linea 0 carácter 0” o variantes aunque normalmente lo de “error 0” se mantiene y empieza a petar todo en cascada. Al principio uno se acojona pero tiene fácil solución, la más básica de todas las soluciones informaticas, salir y volver a entrar ;P

Otras versiones son ya más claras cuando lo que vienen a decir es "he muerto"

A menudo cuando vamos programando forms para web y en el Explorer vamos refrescando llega un momento en que se colapsa y se queda la pantalla gris, pues lo mismo, cerrar y abrir Explorer. (Funciona mucho mejor con Firefox pero como quien manda es el cliente y suelen usar Explorer a saber porque pues…)

Desaparece la toolbar al volver al form inicial.

Oracle forms: Desaparece la toolbar al volver al form inicial.

Oracle forms: Llamo a un formulario con call_form y al salir del segundo desaparece la toolbar.

SITUACIÓN:

En un formulario con toolbar horizontal tengo un botón que llama mediante CALL_FORM a otro formulario parecido también con su toolbar y cuando salgo de este no solo se cierra el formulario si no que desaparece la toolbar y nos queda el form anterior que se desplaza para arriba. ¿Donde está la toolbar?

EXPLICACIÓN:

Cuando salimos de un formulario se cierra la ventana de forms (no la del S.O. si no lo que definimos en forms como Window) mediante una orden interna que desconozco. Como cuando programamos forms no solemos empezar de zero si no que cogemos una plantilla o un form parecido y las ventanas siempre son la misma por lo que cuando el form dice “cerrar window (‘ventana1’)” se encuentra que hay 2 y por eso se cierra también la toolbar del anterior.

SOLUCIÓN:

En caso de forms que se llamen entre ellos renombrar la ventana de uno de ellos para que el nombre sea diferente.

miércoles, 21 de mayo de 2008

No se ejecutan los triggers al cambiar de registro

No se me ejecutan los triggers en Oracle Forms.

Ejecuta trozos de código pero otros no, parece que se los salta.

No salen los alerts pero pasa porque otros cambios que hace el código si se ven.

He intentado post-query, post-record, post-change… y no funciona ningún trigger.

Todo eso nos lleva a pensar ¿Oracle Forms usa caché?

SITUACIÓN:

Tengo un bloque de datos con un código de persona y dependiendo de la primera letra (un substring vamos xD) cambia el valor de un radio button que nos indica el tipo de persona y además nos cambia el nombre de una pestaña (Tab). Para hacer esto recurrimos lógicamente al post-query, que como su nombre indica es el trigger que se ejecutará después de ejecutar la consulta (query) y funcionan bien ambos cambias (tab y radio) mientras vamos cambiando de registro hacia delante pero cuando tiramos hacia atrás solo funciona el del radio button mientras que no funciona el cambio de nombre de la pestaña. Raro raro, lo primero que uno piensa si programaba con Borland C++ para MS-DOS (snif) es que el compilador se salta líneas así que ponemos en el trigger post-query

message (‘Paso por aquí’);

funcion_que_me_cambia_el_radio_button;

message (‘Ala, ya pasé de aquí’);

y ejecutamos: mientras vamos avanzando registros nos sale el mensaje, ejecuta la función y sale el segundo mensaje pero cuando tiramos atrás y nos movemos por los registros que ya hemos visto los mensajes no salen pero si se hacen los cambios de la función. Entonces ¿pasa o no pasa por el trigger? ¿Si pasa porque no salen los mensajes? ¿y si no pasa porque se cambia el radiobutton?

EXPLICACIÓN:

Oracle forms a no ser que le indiquemos lo contrario solo carga un registro y los demás los va consultando a medida que avanzamos con next_Record (sea por código , por teclado o con el ratón) por lo que después de cada uno de ellos ejecuta el trigger post-query pero cuando volvemos atrás estamos consultando los que oracle forms ya ha cargado por lo que no sirven ya los triggers *-query que son los que hacen referencia a la carga de datos y debemos usar los *-record que son los que hacen referencia a la aplicación local por así decirlo, al forms.

SOLUCIÓN:

En el post-query sigue el código para cuando le den a F8 (ejecutar consulta) y vayamos avanzando pero también en el trigger PRE-RECORD para tratar los que ya están cargados. El post no sirve porque nos interesa hacer las operaciones con el registro al que vamos, el que veremos una vez ejecutado el trigger y no nos interesa que lo haga con el anterior puesto que ni lo veremos cuando se hagan los cambios porque ya estaremos en el siguiente.

martes, 20 de mayo de 2008

Como solucionar errores en Oracle Forms

Soy Tomás, informático catalán de 26 años, programando desde los 14 con la pausa alocada típica de la adolescencia superior y profesionalmente desde hace 5 básicamente con PL/SQL y Forms/Reports.

Y una vez presentado os digo la verdad, aunque parezca mucho, no es tanto... que la pausa duró mucho, casi tanto como las resacas, pero los años laborales me han dado un poco de experiencia que es lo que te enseña de verdad porque programar todo el mundo puede hacerlo en un par de días si se pone pero solucionar problemas estúpidos para los que los analistas no encuentran solución y que son bugs o caprichos del programa hay que haber aceptado muchas tocadas de cojones del cliente y cambios inesperados que por simples que sean lo cambian todo.


Es por ello que no voy a poner un manual de oracle forms o la lista de errores copiados de la ayuda si no que a partir de ahora cuando me salga una de estas cosas en vez de olvidarla hasta que me la vuelva a encontrar la escribiré en este blog a modo de recordatorio y ya de paso que sirva de ayuda a alguien más que no se porque hay información de todo menos de oracle forms y reports.

Lógicamente acepto encantado que me conteis los que sepais vosotros para publicarlos y que ayuden a más gente y si conoceis soluciones alternativas pues mejor que mejor :)

Que versión de Oracle Forms usas?