Parámetros opcionales en JasperReports

Trabajando con parámetros opcionales en JasperReports


Teniendo la necesidad de hacer un reporte en JasperReports al cual se le puedan pasar parámetros opcionales, y no encontrando alguna guía en internet  que me dejara las cosas bien claras al respecto, he decidido hacer este remedo de tutorial ya sea para usarlo cuando necesite hacerlo de nuevo y que ya se me haya olvidado o para que le sirva a alguien que necesite hacer lo mismo. 


El requerimiento era que el reporte además de tener ciertos parámetros fijos también tuviera otros opcionales, es decir que el usuario los puede dejar vacíos cuando quiera o especificar unos y dejar otros en blanco indistintamente. 


Para trabajar parámetros normales en JasperReports basta que además de crearlos en la sección "Parameters" del reporte en la ventana "Report Inspector" le agreguemos el prefijo “$P” al nombre del parámetro o visualmente arrastrar con el mouse desde la lista de parámetros a nuestra línea de código del Editor de Expresiones.



Con lo que a mí me quedó un query del tipo: 


SELECT CODCIA, TIPODOC, NUMDOC, FECHAGEN, CANTIDAD
FROM INGRESOSBODEGA
WHERE CODCIA = $P{CodCia} AND TIPODOC = $P{TipoDoc}
AND FECHAGEN >= $P{FechaInicial} AND FECHAGEN <= $P{FechaFinal}


¿Pero qué pasa si queremos hacer que algunos de esos parámetros sean opcionales para el usuario? 


Bueno en teoría basta con agregar al prefijo del nombre, el carácter “!”  y con eso el reporte evaluará la expresión antes de ejecutar el query completo, por ejemplo, yo quiero hacer que los parámetros FechaInicial y FechaFinal sean opcionales


WHERE CODCIA = $P{CodCia} AND TIPODOC = $P{TipoDoc}
AND FECHAGEN >= $P!{FechaInicial} AND FECHAGEN <= $P!{FechaFinal}
 


Pero esto no funcionará porque si el usuario los deja vacíos, la expresión de los parámetros devolverá null y evidentemente el query fallará. 


¿Cómo lo solucionamos? 


Creando un parámetro de tipo String por cada parámetro que nos interese que sea opcional, y desmarcandole la propiedad "Use as a prompt" (Para el caso del parámetro  "FechaInicial" he creado WhereFechaInicial y para el parámetro "FechaFinal" he creado WhereFechaFinal).




Volviendo a nuestro query le sustituimos cada parámetro incluyendo toda la sentencia SQL:


Cambiamos " AND FECHAGEN >= $P{FechaInicial}" por "$P!{WhereFechaInicial}"
y " AND FECHAGEN <= $P{FechaFinal}" por "$P!{WhereFechaFinal}"


Quedando de la siguiente forma: 


WHERE CODCIA = $P{CodCia} AND TIPODOC = $P{TipoDoc}
$P!{WhereFechaInicial} $P!{WhereFechaFinal}


Nos vamos luego al Editor de Expresiones de los parámetros mencionados y ahí definimos el SQL respectivo que se evaluará antes que el query sea ejecutado. Seleccionamos el parámetro "WhereFechaInicial" y editamos su Default Value Expression con una sentencia IF ELSE donde evaluamos el parámetro "$P{FechaInicial}" para definir cuando el usuario lo deja vacío: 


($P{FechaInicial} != null ? " AND FECHAGEN >= '" + $P{FechaInicial + "'" : "")



Lo mismo hacemos con el parámetro "WhereFechaFinal": 


($P{FechaFinal} != null ? " AND FECHAGEN <= '" + $P{FechaFinal + "'" : "")
 


Con lo que hemos hecho el reporte devolverá en cada parámetro Wherexxxx la cadena de la porción SQL correspondiente si el usuario especifica un valor, caso contrario devolverá una cadena vacía. 


Hasta aquí todo perfecto para cualquier parámetro que no sea una fecha. Pero como nuestro caso es precisamente ese … parámetros de tipo fecha!


No nos funciona el query porque el método .toString() de los parámetros java.util.Date nos devuelve el formato “EEE, d MMM yyyy HH:mm:ss Z” (por temas del Locale y otras hierbas) y obviamente no es igual al formato que espera la base de datos, así que para resolverlo hemos tenido que crear una clase Java propia que tenga un método que devuelva la fecha formateada correctamente, eso se hace mediante Scriptlets que trato en la guía Trabajando con Scriptlets en el plugin de iReport en Netbeans de esa forma la expresión del parámetro “WhereFechaInicial” me quedó de la siguiente forma: 


($P{FechaInicial} != null ? " AND FECHAGEN >= '" +
$P{REPORT_SCRIPTLET}.getFecha($P{FechaInicial},"dd/MM/yyyy") + "'" : "")


Hago lo mismo con el parámetro “WhereFechaFinal”, compilo y ejecuto el reporte … Quedó perfecto! 


Espero que le sirva a más de alguno que necesite hacer lo mismo.


Actualización: Es muy importante que cuando se definan los parámetros opcionales queden después de los parámetros normales, pues de lo contrario, al momento de evaluar el valor default de los parámetros opcionales no estarán instanciados los parámetros normales y sus valores siempre serán nulos, por lo que el query no funcionará adecuadamente.


EmoticonosEmoticonos