Esta serie de artículos sobre los reportes interactivos de APEX ya lleva las siguientes entregas:
- Todo sobre reportes interactivos – Parte 1. (Introducción)
- Todo sobre reportes interactivos – Parte 2. (Personalizado de atributos de región y reporte)
- Todo sobre reportes interactivos – Parte 3. (La barra de búsqueda y el menú de acciones)
- Todo sobre reportes interactivos – Parte 4. (Vistas de icono y detalle)
- Todo sobre reportes interactivos – Parte 5. (Personalización de atributos de columna)
Esta sexta entrega se centra en una características que muy pocos desarrolladores conocen y utilizan, como lo es el enlace a los reportes interactivos con parámetros de filtrado específicos.
Existen diferentes maneras de poder filtrar un reporte de APEX en general y de los reportes interactivos en particular. La más conocida de ellas, la utilicé en un ejemplo en la entrega anterior y consiste en crear un elemento de página al que pasamos un valor y luego utilizamos este valor para filtrar los resultados de la consulta SQL. Esto límita el resultado a un grupo específico de registros que cumplen con el filtro definido a nivel del WHERE de la sentencia de consulta que construye el reporte.
Pero, ¿qué pasa si no queremos o no podemos por alguna razón utilizar este método de filtrado por medio de la claúsula WHERE de la consulta?
La respuesta a esta pregunta es lo que vamos a tratar en este artículo.
Existen múltiples escenarios en donde utilizar solamente el where no es suficiente o se vuelve un poco complicado:
- ¿qué hacemos si queremos buscar por criterios varios y aleatorios definidos en otras página?
- ¿qué hacer si tenemos definidos varios reportes guardados y queremos presentar uno de ellos de manera inmediata?
En este artículo vamos a ver como crear estos filtros para utilizarlos desde enlaces, así como las opciones que tenemos disponibles para armarlos.
Los temas a tratar incluyen:
- Restricciones
- Sintaxis
- Ejemplos
Restricciones
Es importante indicar, que cuando se utiliza este tipo de enlace de llamado a reportes interactivos, existen algunas restricciones que debe tener presentes.
- Si en el URL no se define un valor de Request, todos los valores por defecto de la definición del reporte serán cambiados.
- Cuando hay más de una región de reporte interactivo en una página y no se define un valor de Request y además la sección de itemNames no incluye un nombre de columna completo con ID de región estático, se producirá un error.
- Si no se define un valor de Request y la sección de itemNames no incluye un nombre de columna de filtro completo con ID de región estático, se va a crear un filtro en el reporte predeterminado si solo existe una región de reporte interactivo en la página.
- Si utilizamos la sintaxis de URL vieja, el formato f?p, para enlazar a un reporte interactivo a una página que contiene más de un reporte interactivo se producirá un error, pues esta sintaxis solo funciona con páginas que tienen un solo reporte interactivo.
En resumen, ¿qué significa todo lo anterior? Básicamente dos cosas:
- es importante definir un Request para cada solicitud que hagamos,
- aunque no es necesario, si es importante que definamos un identificador estático a cada reporte interactivo que queremos filtrar e incluirlo como parte del URL de solicitud de dicho reporte.
Esto con la finalidad de evitar posibles errores.
Sintaxis
Existen tres sintaxis básicas que podemos utilizar para enlazar con un reporte interactivo:
- La sintaxis de Request.
- Sintaxis de Nombre de Reporte y Valor.
- Sintaxis de Limpiar Cache.
En el caso de la sintaxis de Nombre de Reporte y Valor, podemos utilizar los siguientes operadores:
| Operador | Descripción |
| C | Contiene |
| EQ | Igual que (es el valor por defecto) |
| GTE | Mayor o igual que |
| GT | Mayor que |
| LIKE | Operador LIKE de SQL |
| LT | Menor que |
| LTE | Menor o igual que |
| N | Nulo |
| NC | No contiene |
| NEQ | Diferente (el opuesto de igual que) |
| NLIKE | Operador NOT LIKE de SQL |
| NN | No nulo |
| NIN | No está en (debe “escapar” los valores separados por como con un \ delante y detrás del valor) |
| IN | Está en (debe “escapar” los valores separados por como con un \ delante y detrás del valor) |
| ROWFILTER | El texto de la línea contiene (hace una búsqueda en todas las columnas mostradas en el reporte cuyo tipo sea STRING o NUMBER) |
Veamos primero la sintaxis para enlazar a un reporte interactivo guardado, usando Request.
IR[ID estático de región]_<alias_reporte>
Entre paréntesis cuadrados, debemos colocar el identificador estático que asignamos a la región del reporte interactivo.
Luego del guion bajo, vamos a colocar el alias que asignamos al reporte guardado.
Por ejemplo, si tenemos un reporte de empleados al que le asignamos el identificador estático EMP y hemos guardado un reporte de solo los empleados que tienen un puesto de jefatura al que hemos puesto el alias JEFES, para enlazar desde afuera a este reporte guardado la sintaxis anterior se convertiría en:
IR[EMP]_JEFES
Ahora bien, si queremos realizar el filtrado de una columna, vamos a utilizar la sintaxis de nombre y valor, cuyo formato general es:
IR[ID estático de región]<operador>_<columna_a_filtrar>
donde, operador es uno de los operadores definidos en la tabla de arriba y columna_a_filtrar es el alias de la columna de reporte que queremos filtrar.
Así pues, si queremos mostrar filtrado el reporte con identificador estático EMP y buscar en la columna de nombre del empleado, cuyo alias es ENAME, por cualquier registro que contenga la cadena KING, la sintaxis sería:
IR[EMP]C_ENAME:KING
Recuerde que si hay un solo reporte interactivo en la página, no es necesario proporcionar el identificador estático del reporte, en este caso la sintaxis anterior se convertiría en:
IRC_ENAME:KING
Finalmente, para enlazar a un reporte interactivo y limpiar el cache del mismo, vamos a utilizar la sección ClearCache del URL de llamado a la página que contiene el reporte interactivo. En este caso, podemos usar 3 diferentes opciones para realizar esta operación:
- RR – Para resetear el reporte interactivo y su paginación. Esta opción es el equivalente a que el usuario final una vez levantado el reporte, haga clic en la opción Restablecer del menú de acciones del reporte interactivo, el reporte va a retornar a la forma original definida por el usuario o guardada por el usuario.
- CR – Para limpiar el reporte interactivo y restaurar la paginación del mismo. Lo que hace esta opción es limpiar cualquier definición hecha durante la sesión actual del usuario tales como divisiones de control, agregados, flashback, gráfico, número de líneas a mostrar, filtros, resaltados, cálculos, agrupados y pivotes.
- RP – Para únicamente restaurar la páginación del reporte.
En la siguiente sección, vamos a ver algunos ejemplos específicos del uso de todas estas sintaxis, para que nos quede más claro, dónde y cómo utilizarlas.
Ejemplos
En esta sección les voy a mostrar algunos ejemplos específicos del uso de la sintaxis de enlace a los reportes interactivos y voy a incluir dos tipos de ejemplos:
- enlaces correctos, y
- enlaces inválidos.
Esto con la finalidad de que en caso de que en algún momento tengan un error, cuenten con algunas pistas de que puede estar sucediendo.
Sintaxis válidas
En el primer ejemplo, vamos a incluir un enlace:
- sin valor de Request,
- con un filtro calificado de columna,
- con un identificador de región estático en la sección itemNames del URL.
Este ejemplo crea un filtro en el reporte primario en la región referenciada dentro del nombre del elemento.
Primero veamos como lo haríamos utilizando la sintaxis de URL f?p:
https://hostname:port/ords/f?p=&APP_ID.:2:&SESSION.::::IR[EMP]_ENAME:KING
Si utilizamos la sintaxis de URL amigable de APEX, el mismo ejemplo sería:
https://hostname:port/ords/r/mycompany/hr-app/simple-ir?session=15332852263343&IR[EMP]_ENAME=KING
El siguiente ejemplo muestra como limpiar las definiciones hechas a un reporte, utilizando la opción CR.
Sintaxis f?p:
https://hostname:port/ords/f?p=213:18:&SESSION.:::CR
Sintaxis de URL amigable:
https://hostname:port/ords/r/demo/sample-reporting/linking-to-interactive-reports?clear=CR&session=9468567580849
El siguiente ejemplo, retorna el reporte a los valores por defecto definidos por el desarrollador, con el uso de la opción RR.
Sintaxis f?p:
https://hostname:port/ords/f?p=213:18:&SESSION.:::RR
Sintaxis de URL amigable:
https://hostname:port/ords/r/demo/sample-reporting/linking-to-interactive-reports?clear=RR&session=9468567580849
En el ejemplo a continuación, restauramos la paginación del reporte, usando la opción RP.
Sintaxis f?p:
https://hostname:port/ords/f?p=213:18:&SESSION.:::RP
Sintaxis de URL amigable:
https://hostname:port/ords/r/demo/sample-reporting/linking-to-interactive-reports?clear=RP&session=9468567580849
En el siguiente ejemplo, veamos como llamar un reporte guardado con el alias “status” , además de limpiar las definiciones que pueda tener el mismo, esto último con el uso de la opción RR.
Sintaxis f?p:
https://hostname:port/ords/f?p=213:18:&SESSION.:IR_status::RR
Sintaxis de URL amigable:
https://hostname:port/ords/r/demo/sample-reporting/linking-to-interactive-reports?request=IR_status&clear=RR&session=9468567580849
Sintaxis inválidas
Ahora veamos algunas sintaxis inválidas, las cuales producirán un error debido a situaciones específicas.
En la sección de restricciones más arriba, se mencionó que una de ellas, es que no podemos utilizar la sintaxis f?p para llamar una página con múltiples reportes interactivos, pues solo funciona para un solo reporte interactivo. El primer ejemplo muestra una sintaxis que ocasionaría un error al llamar a un reporte interactivo si la página tienen varios reportes interactivos:
https://hostname:port/ords/f?p=&APP_ID.:8:&SESSION.:IR_REPORT_mine:::ENAME:KING
En el próximo ejemplo, vamos a suponer que en la página destino existe más de un reporte interactivo. En el URL no incluimos un Request, tampoco un filtro de columna con un identificador estático de región, por lo tanto el motor de APEX no sabe a cual de los reportes aplicar la llamada y se producirá un error:
https://hostname:port/ords/f?p=&APP_ID.:2:&SESSION.::::ENAME:KING
Finalmente, este último ejemplo tiene un enlace con dos valores de Request separados por coma y no contiene un filtro de columna calificado que incluya el identificador estático de la región en la sección de nombre de elemento del URL, por lo que también se producirá un error pues no está claro en donde se debe crear el filtro:
https://hostname:port/ords/f?p=&APP_ID.:2:&SESSION.:IR[test]_employee,IR[test2]_dept10:::ENAME:KING
Ejemplo práctico
Veamos que sucede cuando ponemos lo anterior en práctica.
En la primera entrega de esta serie, creamos una aplicación con algunas páginas que tienen diferentes reportes interactivos, vamos a usar dos de ellos para poner en práctica la teoría.
En primer lugar tenemos la página de proyectos, que contiene un reporte interactivo que luce como el de la imagen a continuación.
También tenemos una página con reporte interactivo de Hitos relacionados con los diferentes proyectos y que luce similar a la imagen a continuación.
Como puede observar en esta última imagen, en la primera columna se incluye el nombre del proyecto.
En mi aplicación, la página del reporte de proyectos es la número 2 y la de hitos corresponde a la página 6.
Teniendo esto en cuenta, queremos filtrar el reporte interactivo de hitos con una selección hecha por el usuario en la página 2, donde se encuentra el reporte de proyectos y que también muestra el nombre de los mismos.
Podríamos crear un campo oculto en la página 6 y pasar el valor del proyecto a este campo y utilizarlo para filtrar el reporte desde la claúsula WHERE del mismo. Esto funcionaría muy bien si la única manera de acceder al reporte de histos es desdel el reporte de proyectos y solo quisieramos ver los hitos del proyecto seleccionado. Sin embago, el reporte de hitos es un reporte general que se puede acceder desde el menú principal y como tal tiene acceso a todos los hitos sin importar al proyecto que pertenezcan.
Aquí es cuando entra en juego la teoría presentada en este artículo, ni es necesario crear diferentes reportes, si podemos utilizar el que ya tenemos y llamarlo con diferentes opciones de filtro de acuerdo con lo que el usuario necesite.
¿Cómo aplicamos la teoría?
Lo primero que vamos a hacer el modificar el reporte de proyectos (de hecho es el único que vamos a modificar, pues el reporte de hitos va a permanecer tal cual lo definimos en la entrega inicial de esta serie.
Para modificar el reporte de proyectos:
- Abra en el diseñador de páginas, la página con el reporte interactivo de proyectos, en mi caso la página 2.
- Haga clic en el panel de la izquierda sobre el nombre de la región del reporte interactivo, que en mi caso se llama Proyectos.
- En el editor de propiedades, en el panel derecho de la pantalla, en las propiedades de región:
- Localize el atributo Origen – Tipo y seleccione la opción Consulta SQL.
- En el atributo Origen – Consulta SQL, modifique la consulta por defecto por la siguiente:
select ID, STATUS_ID, '' || NAME || '' as NAME, DESCRIPTION, PROJECT_LEAD, BUDGET, COMPLETED_DATE, CREATED, CREATED_BY, UPDATED, UPDATED_BY from EBA_PROJECTS
- Guarde los cambios y ejecute la página.
El reporte de proyectos ahora lucirá como en que muestra la siguiente imagen.
Como habrá notado, en la columna Nombre del reporte aparece el código HTML de un enlace, recordemos que por seguridad los caracteres especiales son escapados de manera general en un reporte APEX..
Para ver la columna como un enlace y que muestre el nombre del proyecto, debemos deshabilitar el escapado de los caracteres especiales.
Para hacer esto:
- Expanda el nodo Columnas que se encuentra en el panel izquierdo de la página, justo debajo del nombre de la región.
- Haga clic en la columna NAME.
- En el editor de propiedades (panel derechos de la pantalla:
- Localice el atributo Seguridad – Caracteres especiales de escape y apague el interruptor del mismo
- Guarde los cambios y ejecute nuevamente el reporte.
Ahora el reporte de proyectos, lucirá como el que muestra la imagen de abajo. En donde en la columna de Nombre, podemos ver un enlace que muestra el nombre del proyecto.
Si hacemos clic sobre cualquiera de los nombres de proyectos, deberiamos poder ver el reporte de hitos.
Sin embargo, nos vamos a topar con un gran error que dice: “No se ha proporcionado ningún total de control para el procedimiento de presentación de una página que requiere un total de control cuando se transfieren como parámetros uno o más valores de argumento, limpieza de cache o solicitud.”, tal y como se muestra la siguiente imagen.
¿Qué es lo que está sucediendo?
Desde hace algunas versiones de APEX atrás, por razones de seguridad, cuando pasamos parámetros a una página po queremos limpiar el cache o la solicitud hecha a una página, debemos calcular y proporcionar un total de control (checksum) como parte del URL para verificar que no se esté queriendo modificar de forma indebida los datos de la página destino.
Para evitar esto, entonces debemos calcular este total de control e incluirlo en el enlace de llamado al reporte de hitos, para lo cual, APEX nos proporciona la función GET_URL del paquete APEX_PAGE, la cual nos va a devolver un URL bien formado que eliminará el error anterior.
Para hacer esto, vamos a cambiar la consulta del reporte de proyectos una vez más y vamos a utilizar la siguiente sentencia:
select ID,
STATUS_ID,
' NAME) || '>' || NAME || '' as NAME,
DESCRIPTION,
PROJECT_LEAD,
BUDGET,
COMPLETED_DATE,
CREATED,
CREATED_BY,
UPDATED,
UPDATED_BY
from EBA_PROJECTS
Al guardar y ejecutar nuevamente el reporte, si tenemos el atributo de escape de caracteres especiales encendidos, obtendremos un reporte similar al que se muestra en la imagen a continuación.
Como puede ver, en el recuadro en rojo se encuentra un nuevo parámetros “cs” que proporciona un valor largo, que corresponde al total de control calculado para el registro específico.
Si apagamos el atributo y guardamos nuevamente el reporte, al ejecutarlo, tendremos nuevamente el enlace con el nombre del proyecto en la columna Nombre.
Al hacer clic sobre cualquiera de los nombre, ahora podremos ver sin ningún problema el reporte interactivo de hitos con todos aquellos hitos que pertenezcan al proyecto seleccionado, en caso de que tenga alguno.
Puede observar el resultado en la siguiente imagen.
Si queremos permitir únicamente poder ordenar por el encabezado de la columna, deshabilitamos (apagamos) los atributos Ocultar, Filtro y División de Control y el resultado se vería de esta manera.
Como puede apreciar en la imagen, ahora tenemos definido un filtro con el valor proporcionado que dice “Identificador de Proyecto contiene ‘Train Developers'” y, en la columna inicial justo los valores de esa columna que corresponden con el mismo. Ambos los he marcado con recuadros rojos para que se pueda apreciar mejor.
Ahora solo resta que hagan sus pruebas y esperen la siguiente entrega de esta serie sobre reportes interactivos.



