Está en la página 1de 6

Gua rpida para usuarios de CrystalReports

Reports (1 parte) (reeditado)


CrystalReports es una potente herramienta de generacin de informes que viene includo en el programa de
desarrollo Visual Studio y permite su utilizacin con la tecnologa .NET.
He decidido escribir unas lneas acerca de este tema porque me he visto en la necesidad de utilizarlo y he tenido
muchos y muy diversos problemas, algunos de ellos considero que son bugs de la aplicacin. A modo de
solidarizarme con futuros usuarios, he decidido dar una rpida idea de los comandos bsicos y finalmente unas
consideraciones y consejos para que cuando alguien se ponga con ello no se le consuma la paciencia como me
ha pasado a m.
No voy a pegar capturas de pantalla ni cosas as; creo que ya somos mayorcitos como para buscar dnde estn
las cosas, a poco que juguis un poco con ello veris dnde est todo, y adems me da pereza, as que me
centrar en los aspectos ms importantes y si alguien tiene algn problema que no dude en ponerse en contacto
conmigo o deje algn comentario aqu. Le atender gustosamente.
Lo bsico:
- CrystalReports (CR) permite la utilizacin de diversas fuentes de datos: desde ficheros word, excel, objetos OLE,
distintos sistemas de bases de datos y ficheros estructurados, como XML.
- Precisamente debido a esta diversidad en la fuente de los datos, CR se ve obligado a utilizar un lenguaje de
consulta o pseudo-SQL muy bsico y a veces consideraremos que limitado.
- Se permite aadir cuadros, tablas, lneas, en el diseador. Se pueden aadir secciones nuevas, aunque
inicialmente tendremos cinco: encabezado de informe (slo se reproducir en la primera pgina del informe),
encabezado de pgina (para todas las pginas), detalles (la parte ms interesante), pie de pgina(para todas las
pginas) y pie de informe(slo se reproducir en la ltima pgina del informe).
- La seccin Detalles es la ms interesante, pues constituye el cuerpo central del informe y nos permitir mostrar
los datos que queramos volcar en el informe. Su uso es muy especial, pues cuando arrastramos un campo de
datos a esta seccin, solamente es necesario incluirla una vez, pues internamente lo que se aplicar es un
iterador mientras existan datos que mostrar.
- Para seleccionar los datos que queremos mostrar existe un asistente de seleccin, que llama CR. Es aqu donde
entra en juego el pseudo-SQL que haba citado. MUY IMPORTANTE: todos los campos que incluimos en un
informe dado se basan en una misma consulta SQL. Si quisiramos mostrar unos datos que no tengan nada que
ver con el resto, o que pretendamos que sean excluyentes, organizados por distinto tipo etc., deberemos utilizar
subinformes.
- Los subinformes se insertan en un informe de la misma manera que se inserta cualquier elemento de diseo en
un informe. Al insertar un informe dentro de otro, si tiene algn tipo de relacin el informe hijo con respecto al
padre, no olvidis actualizar la pestaa Vnculos en el cual especificaris qu relacin deseis establecer.
Hasta ah yo creo que est lo bsico. En otra entrega explicar qu necesitamos para invocar desde un cdigo en
.NET a un informe ya creado. Un saludo.

Reports (2 parte) (reeditado)
Cdigo:
El cdigo que voy a pegar est en Visual Basic para .NET, pero para C#, por ejemplo, sera prcticamente
idntico. Hay conversores de un lenguaje a otro que lo hacen muy bien, y tampoco es nada complicado realizarlo
a mano. De todos modos, si tenis algn problema no dudis en consultarme.
Paquetesnecesarios:

Imports CrystalDecisions.Shared
Imports CrystalDecisions.ReportSource
Imports CrystalDecisions.Windows
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.ReportAppServer
Imports System.Diagnostics
Comandos, instrucciones tiles:
Creacin de un informe genrico
Dim vd As New ReportDocument()
Otra opcin, quiz ms til porque permite hacer ms cosas: crear el informe de la propia clase del informe que
hemos creado:
Dimvd As New informeMio()

Ahora creamos el formulario que va a contener el informe:
DimfrmReportes As New informeContenedor()

Atencin: el orden de estos comandos que indico a continuacin es este; si se hace en otro orden los efectos
pueden ser imprevisibles: que no coja los parmetros bien, que no conecte, que no rellene nada en el informe
vd.Load(informeOfertaMaq.rpt) carga el informe
otras posibilidades para cargar informes:
vd.OpenSubreport(subinforme.rpt)
para acceder a sus propiedades:
vd.Subreports(0).

y ahora ya SetDataBaseLogon, SetDataSource, SetParameterValue, etc. Para establecer login de la base de
datos a utilizar, almacen de datos de entrada:
vd.SetDatabaseLogon(webuser, webuser) datos de login
vd.SetDataSource(dataset)

un dataset que contiene los datos de entrada del informe. Opcional; til si se va a migrar la BD a otro servidor. Ya
hablar en otra ocasin del inters que tiene el origen de los datos.
Seguimos: establecer parmetros (de existir stos):
vd.SetParameterValue(clave, valor)
Cargar el informe en el formulario, en un control que se llama CrystalReportViewer. Establecer que el informe que
se va a cargar en este control va a ser el que acabamos de crear. No olvidis que para que esta instruccin
funcione tenis que establecer como pblico el control CrystalReportViewer

frmReportes.CRVinforme.ReportSource = vd
frmReportes.ShowDialog() mostrar formulario
Bueno, he tratado de explicar un elenco de comandos que tenemos a nuestra disposicin a la hora de crear y
cargar informes. En la prxima entrega sintetizar una serie de comandos mnimos necesarios para que podis
cargar un informe cualquiera sin ningn problema.

Tambin os dar unos consejos muy tiles a tener en cuenta a la hora de manejar informes. Os quitarn muchos
dolores de cabeza, puedo asegurarlo. Creo que ser la entrega ms interesante, porque lo que he explicado hasta
ahora lo poda haber encontrado cualquier programador mnimamente espabilado sin ms que jugar un poco con
el Visual Studio y buscar en internet. Un saludo.


Reports (3 parte) (reeditado)
Bien, vamos con la parte ms interesante. Por lo menos eso creo yo; si estas cosas me las hubiera dicho alguien
antes de ponerme a pelearme con ello hubiera ahorrado un tiempo valiossimo, que en lugar de haberlo
desperdiciado comindome el coco hubiera empleado en en bueno, es igual.
Se trata de una serie de consejillos que he ido anotando y recolectando y que he agrupado como he podido. Espero
que os sean de utilidad.
1.- Una cuestin de diseo: si tenis que pegar cuadritos de manera que queden lo mejor ajustados posible, es
mucho mejor que optis por dibujar un cuadro grande y dividirlo con lneas. El diseador es malsimo y ajustar
cuadros contiguos para que se alineen perfectamente puede provocar irritacion en vuestros ojos, os lo aseguro. En
general toda operacin de alineacin de elementos en el diseador es desastrosa.
2.- El origen de los datos: dos posibilidades bastante interesantes con las que yo he trabajado: tablas estticas y
XML. La primera opcin es bastante interesante si la red en la que estis trabajando ser la que se utilizar
finalmente en la implantacin de la aplicacin, porque como migris a otro servidor de base de datos la aplicacin
CR no encontrar las tablas, las tendris que volver a cargar y se os borrarn todos aquellos campos que pintbais
en el informe, con lo cual tendris que volver a trabajar.
Es por esto por lo que propongo la segunda opcin. Con esta opcin la fuente de datos es un objeto ADO, que
carga un XML con la estructura de los datos que va a manejar el informe. Con esto se independiza de todo lo
dems: servidor, login, usuario etc, para quedarse con lo que realmente le interesa al informe: la estructura de los
datos que va a cargar. La mejor idea es construir un procedimiento almacenado (pl/sql) que nos devuelva slo y
exclusivamente aquellos datos con los que vamos a trabajar en el informe (as no tendremos que hacer join de
tablas ni nada de eso ); crear un objeto XML con Visual Studio y arrastrar el pl/sql que deseamos. Despus
establecemos como origen de datos en el informe tal fichero xml y ya est. As de fcil.
3.- Si optis aun as por la creacin de varias tablas u os veis obligados a, de una u otra manera utilizar varias
tablas en el informe, no os olvidis de revisar su vinculacin en la solapa correspondiente del Asistente de Base de
Datos. Normalmente aqu el CR hace bastante bien su trabajo, pero no es omnipotente y a veces se puede confundir
si los nombres de los campos son un tanto ambiguos.
4.- A colacin de esto ltimo, por defecto CR vincula las tablas con un join natural (innerjoin); si deseis un join a
izquierdas (para que si encuentra un nulo en un campo de unin no deje el informe el blanco y, en lugar de eso,
rellene hasta donde pueda) haced clic derecho sobre el vnculo y en la opcin correspondiente a propiedades del
vnculo podris jugar un poco con la vinculacin: natural, a izuierdas, de igualdad, desigualdad estricta o no etc.
5.- A veces se cambian las fuentes de datos de un informe quedan algunos residuos, como por ejemplo si existe
por ah alguna consulta a la que obedece la generacin del informe (un select, vamos; el asistente de consultas).
Para evitar este doloroso quebradero y no perdis demasiado tiempo, PRIMERO borrad la consulta del Asistente de
consultas y DESPUS eliminad la fuente de datos, en este orden. No es necesario que borris a mano los campos
que aparecan en el informe; el solito se encarga de hacerlo (de ah el problema de migracin de servidores de
bases de datos que comentaba en el punto 2).
6.-Cuando se inserta en la seccin Detalles algn campo de la fuente de datos, automticamente en la cabecera
aparece el nombre del campo subrayado. Esto se puede cambiar, eliminar, etc. Si se elimina el campo, desaparece
su cabecera.
7.- Os puede ocurrir que no encuentre el informe al ejecutar (debug) el programa. Esto se soluciona copiando la
ltima versin del fichero .rpt en el directorio bin de la solucin, donde se genera el ejecutable. No olvidis, si es
este el caso, copiar la ltima versin del informe en este directorio o, lgicamente, no veris los cambios.
8.- Un detalle importante: a veces, sobre todo en la creacin de subinformes, como veremos luego, y en su
vinculacin con el padre, necesitaremos que aparezcan campos en el informe, pero invisibles. Nota, listillos: CR no
maneja el atributo Visible=false en los controles que se introducen en el informe. As que nos conformaremos con
una solucin mucho ms arcaica pero eficiente: pintar los campos que deben estar presentes pero no verse del
mismo color que el fondo del papel; habitualmente, blanco, lgico.
9.- Ojo al crear campos de parmetro en el informe: el tipo con que los declaris es importante. Si luego intentis
en el Asistente de Consultas comparar este parmetro con un campo de la fuente de datos y no coinciden los tipos
no aparecer (como parece obvio; no podemos comparar un datetime con un numeric, por ejemplo).
10.- En cuanto a la vinculacin de informes padre e hijos, se pueden contar bastantes cosas: normalmente la
condicin de lo que se muestra en el hijo se puede hacer desde la propiedad del subinforme vinculacin (clic
derecho del ratn sobre el control subinforme recin aadido). De ah la utilidad del punto 8. Podis coincidir un
parmetro que es un id para el informe padre y un fk del subinforme (me segus? el tpico caso de informacin
relacionada que interesa tener en un informe pero, por cuestiones de integridad en distintas tablas). Qu pega hay
en todo esto? pues que en el combobox que aparece en la parte de abajo en el cuadro de dilogo solamente sugiere
campos para vincular que APARECEN en el subinforme (no todos los que tiene el subinforme, como parecera ms
til), lo cual considero una limitacin bastante grande. Solucin: punto 8, si no queris que en vuestro subinforme
se pinten identificadores, claro.
11.- En cuanto a la insercin de subinformes: primero insertad objeto subinforme, elegid el informe a pegar,
colocadlo, y despus estableced la vinculacin padre-hijo. En este orden, porque al elegir el informe destino a
encasquetar se os da la opcin de establecer la vinculacin pero ya os digo yo que no funciona bien. Es mejor
hacerlo despus y comprobar que no se ha perdido, porque a veces introduces la vinculacin y al volver a hacer
clic derecho y comprobar oh, sorpresa!, a desaparecido. Otra cosa, si vais a pegar varios subinformes dentro de
un mismo padre, pegad cada uno en una seccin diferente (Asistente de seccin; clic derecho sobre el nombre de
una seccin) para que no se os solapen unos con otros.
12.- Si hacis algn cambio en el subinforme, no olvidis actualizar su aparicin en el padre (clic derecho sobre el
control subinforme.) o los cambios no se harn efectivos.
13.- Las secciones que se pueden aadir tienen las propiedades que las rplicas de las que se clonan; es decir:
secciones tipo detalles (que repetirn sus contenidos mientras queden datos),
secciones tipo encabezado y pie de pgina (que debern caber en una pgina) y del tipo encabezado y pie de
informe (que irn al principio y al final del informe y debern caber en una pgina).
14.- Por ltimo, existe la opcin de hacer que no se muestre un subinforme si ste se encuentra vaco de contenido
(la consulta no ha devuelto datos y estara en blanco). Para ello, haced que el subinforme se cargue en una
subseccin (una opcin muy recomendable, lo de insertar los subinformes en subsecciones propias, porque as se
autoajustan los espacios en blanco para que no haya huecos), y en las opciones contextuales de esta seccin
existe una para ocultar la seccin si est en blanco. Marcadla y ya est. Repito, esta opcin es muy interesante para
dar una presentacin al informe como debe ser, suprimiendo espacios blancos innecesarios cuando, por cualquier
circunstancia, la consulta que carga el subinforme no devuelve nada y el subinforme se cargara en blanco.
Finalmente, este es el cdigo que a mi me funciona. Para los que deseen ms informacin, no tienen ms que echar
un vistazo a la segunda parte de esta pequea gua. Lo que hago es crear un informe de la clase del informe
concreto que pretendo generar, indicar la fuente de datos (DataSet) de los subinformes contenidos, indizados en un
array, establecer la fuente de datos del informe padre o contenedor principal, establecer sus parmetros y abrir el
formulario que contendr el control CrystalReportViewer, que me permitir mostrar el informe. Este esquema
funciona; comprobado.
DiminformeOferta As New informeOfertasVenta()
informeOferta.Subreports(0).SetDataSource(datosSeleccionado1.Tables(0))
informeOferta.Subreports(1).SetDataSource(datosSeleccionado2.Tables(0))
informeOferta.Subreports(2).SetDataSource(datosSeleccionado.Tables(0))
informeOferta.SetDataSource(listaOfertas.Tables(0))
informeOferta.SetParameterValue(id_oferta, idOfertaSeleccionada)
frmReportes.CRVinforme.ReportSource = informeOferta
frmReportes.ShowDialog()
Esto es todo. Soy consciente de que me explico fatal, as que si alguien tiene algn problema que no dude en
envirmelo y le atender con gusto.