Está en la página 1de 16

QuickReport

Autor:
Nstor Freire
nestorfreire@ElRinconcito.com
Prohibida la reproduccin total o parcial sin permiso explcito del autor.
1
Personalizacin de QuickReport
Previsualizacin (Preview) a medida con QuickReport 2.
Curiosamente, la personalizacin del Qreport suele dar problemas, cuando, en realidad, esto es bastante
sencillo y no se necesita ningn componente adicional. Para hacerlo slo se precisan dos cosas: un
TQuickRep y un TQRPreview. El primero tiene un evento OnPreview, al que llama cuando se usa el
correspondiente procedimiento Preview. Si este evento no tiene nada asignado, todo se ejecuta de manera
normal y segn el diseo tradicional, pero si se le asigna un procedimiento no muestra el tpico formulario,
sino que hace lo que en ese evento se diga.
Modificamos el OnPreview
Analizando el formulario de un Preview normal, se pueden ver varios botones y las pginas con texto
debajo. se es el TQRPreview. Entonces, si se quiere personalizar la visualizacin del QReport, lo nico que
hay que hacer es crear nuestro formulario personal, cambiar el evento y usar el Preview. Para poder asignar a
TQRPreview el texto correspondiente, hay que modificar su propiedad QRPrinter, que no indica lo que se va
a imprimir, como puede parecer, sino a mostrar. Para manejar esto, hay que poner en el USES las unidades
quickrpt y qrprntr.
Para nuestro formulario podemos poner los botones tpicos y sus imgenes, o disear los nuestros,
incluyendo etiquetas y cualquier otro control.
Para dar un ejemplo montar una aplicacin donde se pueda elegir la visualizaci n estndar o la
personalizada. Para mayor comodidad no crear ni destruir ningn formulario en ejecucin.
Empezaremos con uno que tenga dos CheckBoxs (Normal y Person) y un botn. En un segundo formulario
tendremos el QuickReport ya preparado, y completamente hecho, con el nombre de QRep1.
procedure TForm1.Button1Click(Sender: TObject);
begin
With Form2 do
Begin
if Normal.Checked then QRep1.OnPreview := ni else QRep1.OnPreview := Muestra;
QRep1.Preview;
end;
end;
La funcin Muestra se encuentra en el Unit2 y, como su nombre indica, muestra nuestro formulario. Este es
su cdigo:
Uses Unit3, quickrpt, qrprntr
procedure TForm2.Muestra (Sender : TObject);
begin
with Form3 do
begin
QRPrev.QRPrinter :=TQRPrinter(Sender); //Mostrar el texto correspondiente
sePage.Value :=QRPrev.QRPrinter.PageNumber; //Inicializar valores
QRPrev.PageNumber:=sePage.Value;
sePage.Value :=1;
sePage.MinValue :=1;
sePage.MaxValue :=QRPrev.QRPrinter.PageCount;
QRPrev.Zoom :=100;
ZoomTo100.Down :=True;
spZoom.Value :=100;
Show;
end;
end;
2
Personalizacin de QuickReport
Con este cdigo lo primero que hacemos es crear el objeto TQRPrinter, que est en la unidad qrprntr y
luego le asignamos el texto que corresponde. A partir de aqu se puede hacer como se quiera, que para eso se
llama personal-izado :-).
Despus doy los valores necesarios para que los controles funcionen como deben.
Para dar un ejemplo de personalizacin, crear un formulario parecido al de QReport, pero con tres cambios:
uno permite situarnos en cualquier pgina, el otro usar cualquier zoom y adems hay una barra de
informacin abajo.
Para tener una idea de cmo puede quedar, esta imagen da una buena pista.

Los controles, de izquierda a derecha son : sePage, sbFirstPage, sbPreviousPage, sbNextPage, sbLastPage,
spZoom, ZoomToFit, ZoomTo100, ZoomToWidth, PrintSetup, Print y Exit. Abajo est StBar.
Asignacin de imgenes
Para asignar las imgenes correspondientes y sus ayudas para que queden como un QReport normal, en el
evento OnCreate del formulario escribimos el siguiente texto:
procedure TForm3.FormCreate(Sender: TObject);
begin
sbFirstPage.Glyph.Handle :=LoadBitmap(hinstance, 'QRFIRSTPAGEBITMAP');
sbPreviousPage.Glyph.Handle :=LoadBitmap(hinstance, 'QRPREVPAGEBITMAP');
sbNextPage.Glyph.Handle :=LoadBitmap(hinstance, 'QRNEXTPAGEBITMAP');
sbLastPage.Glyph.Handle :=LoadBitmap(hinstance, 'QRLASTPAGEBITMAP');
ZoomToFit.Glyph.Handle :=LoadBitmap(hinstance, 'QRZOOMTOFITBITMAP');
ZoomTo100.Glyph.Handle :=LoadBitmap(hinstance, 'QRZOOMTO100BITMAP');
ZoomToWidth.Glyph.Handle :=LoadBitmap(hinstance, 'QRZOOMTOWIDTHBITMAP');
PrintSetup.Glyph.Handle :=LoadBitmap(hinstance, 'QRPRINTSETUPBITMAP');
Print.Glyph.Handle :=LoadBitmap(hinstance, 'QRPRINTBITMAP');
ZoomToFit.Hint :=LoadStr( SqrZoomToFit );
ZoomTo100.Hint :=LoadStr( SqrZoom100 );
ZoomToWidth.Hint :=LoadStr( SqrZoomToWidth );
sbFirstPage.Hint :=LoadStr( SqrFirstPage );
sbLastPage.Hint :=LoadStr( SqrLastPage );
3
Personalizacin de QuickReport
sbPreviousPage.Hint :=LoadStr( SqrPrevPage );
sbNextPage.Hint :=LoadStr( SqrNextPage );
PrintSetup.Hint :=LoadStr( SqrPrinterSetup );
Print.Hint :=LoadStr( SqrPrintReport );
end;
Las imgenes se pueden cargar de un archivo de recursos que ya viene incorporado con QuickReport, el
Quickrpt.res, y las constantes estn en qr2cons.dcu o qr3cons.dcu, dependiendo de la versin que se utilice
Cargar pginas y progreso.
Para que cargue las hojas, no hay que hacer nada, pero s se puede indicar el progreso de esto. Cada vez que
lee una nueva pgina, llama al evento OnPageAviable para facilitarnos la tarea. Aqu podemos escribir algo
como
procedure TForm3.QRPrevPageAvailable(Sender: TObject; PageNum: Integer);
begin
sePage.MaxValue :=PageNum; //Ajustar el contador y la
StBar.Panels[0].Text :='Pag. 1/' +IntToStr(PageNum); //barra de tareas
//Poner un ttulo
if QRPrev.QRPrinter.Title ='' then QRPrev.QRPrinter.Title :='SIN TITULO'; //si no lo tiene ya
if PageNum =1 then
Caption :=QRPrev.QRPrinter.Title +' - 1 pagina'
else
Caption :=QRPrev.QRPrinter.Title +' - ' +IntToStr(PageNum) +' paginas';
case QRPrev.QRPrinter.Status of //Definir su estado
mpReady: Caption :=Caption +' LISTO';
mpBusy: Caption :=Caption +' LEYENDO';
mpFinished: Caption :=Caption +' TERMINADO';
end;
MaxPag :=PageNum;
StBar.Panels[2].Text :='Nombre : ' +QRPrev.QRPrinter.Title;
end;
El zoom, el cambio de pginas y a imprimir.
Una vez visto hasta aqu, lo que falta ya no es mucho, solamente el cdigo de los botones, que no es
complicado. En el SpinEdit que modifica el zoom, slo hay que cambiar la propiedad Zoom del QRPrev y
actualizar la barra de tareas.
procedure TForm3.SpZoomChange(Sender: TObject);
begin
QRPrev.Zoom :=SpZoom.Value;
StBar.Panels[1].Text :='Zoom ' +IntToStr (spZoom.Value);
end;
El que cambia la pgina tiene que hacer poco, pero es importante:
4
Personalizacin de QuickReport
procedure TForm3.SePageChange(Sender: TObject);
begin
QRPrev.PageNumber :=sePage.Value;
StBar.Panels[0].Text :='Pag. ' +IntToStr(sePage.Value) +'/' +IntToStr(MaxPag);
end;
Este es el nico lugar donde se indica a la barra de tareas la pgina actual y esto, pese a que hay otros cuatro
botones que la cambian; pero como todos ellos actualizan este control, no hace falta ms.
Para ir a la primera pgina:
procedure TForm3.sbFirstPageClick(Sender: TObject);
begin
sePage.Value :=1;
end;
Ir a la siguiente de la posicin actual (si hay ms):
procedure TForm3.sbNextPageClick(Sender: TObject);
begin
if sePage.Value <QRPrev.QRPrinter.PageCount then
begin
sePage.Value :=sePage.Value +1;
end;
end;
Para los otros botones slo hay que usar la propiedad QRPrev.QRPrinter.PageCount o disminuir la
propiedad Value de sePage, para ir a la ltima o la anterior pgina, respectivamente.
Para ajustar la pgina al largo o al ancho (ZoomToFit y ZoomToWidth respectivamente) el cdigo es casi
igual, por lo que slo pondr de uno de ellos.
procedure TForm3.ZoomToFitClick(Sender: TObject);
begin
QRPrev.ZoomToFit;
spZoom.Value :=QRPrev.Zoom;
end;
Para aumentar el zoom al 100, se cambia la propiedad zoom de QRPrev.
Los nicos botones que quedan son los de impresin, que merecen un comentario aparte. Se trata de que
QRPrev tiene su propio cuadro de configuracin, pero para indicar si se ha cancelado o no, cambia el valor de
su propiedad Tag. Este es 1 si se cancela y 0 si se acepta; por ello no debemos almacenar ningn valor aqu
si usamos su cuadro de dilogo:
procedure TForm3.PrintSetupClick(Sender: TObject);
begin
with Form2.QRep1 do
begin
tag :=-1;
PrinterSetup;
if tag =0 then
print;
end;
end;
5
Personalizacin de QuickReport
Imprimir es ms fcil; nicamente hay que dar la orden de que lo haga.
procedure TForm3.PrintClick(Sender: TObject);
begin
QRPrev.qrprinter.Print;
end;
Y ahora, lo que queda es liberar el objeto QRPrinter que creamos al mostrar el formulario y ocultar ste:
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
QRPrev.QRPrinter :=nil;
Form3.Visible :=False;
end;
TQuickReport
6


Manejo de datos y expresiones

El uso ms normal de TQuickReport es poner unas bandas, asignar una base de datos y previsualizar. Con
este artculo intentar explicar otras funciones de este generador de informes, que bien usado puede hacer
maravillas y sin escribir ni una sola lnea de cdigo (aunque esto no siempre es posible). Para ello, usar
QuickReport 3.0.5, Delphi 5 y los controles que vienen en la instalacin completa de la versin Profesional
del mismo. En otras versiones puede que no estn incluidos algunos de los controles de los que hablar o el
cdigo no sea completamente compatible. De todos modos, en la mayora de los casos no es un problema
insalvable.

Exportacin de informes

Exportar es muy sencillo. Hay cuatro tipos de exportacin, que varan segn el formato deseado. stos son:

Extensin Descripcin Control
.QRP Exportacin estndar. Es el nico que permite importar Ninguno
.TXT Archivo de texto. El resultado es muy parecido a lo que se ve en pantalla TQRTextFilter
.CSV Archivo de Excel. Resultado un poco catico, pero se puede arreglar. TQRCSVFilter
.HTML No genera saltos ni nada parecido, y necesita algunos retoques, pero
puede ser muy til para publicar los listados en Internet.
TQRHTMLFilter

La extensin .QRP es la que ms espacio necesita, pero es la nica que permite cargar informes. Este
formato siempre est disponible, sin controles aparte.
En realidad, hay mas controles de los que nombro, pero sos estn en la versin Enterprise de Delphi 5, y se
usan igual que los que he mencionado, por lo que no hablare de ellos.
Para dar una idea de cunto puede ocupar un informe, he creado uno con 11 hojas, tipo Master/Detail,
controles de pie de pgina y ttulo. Lo he guardado en los cuatro formatos, y stos son los resultados:

Extensin Tamao
.QRP 512 Kb
.TXT 22 Kb
.CSV 30 Kb
.HTML 74 Kb

Llama la atencin el exagerado tamao de .QRP, pero (supongo) se debe a que no guarda los datos, como las
otras extensiones, sino que, adems, guarda las bandas, etiquetas, propiedades, etc. sin necesidad de ninguna
lectura posterior a las bases de datos.
Y ahora, por fin, explico cmo se puede hacer. Se coge el control, o los controles, de los antes mencionados,
que se desee y se deja caer sobre el mismo formulario donde se encuentra el Q.Report. Con esto ya aparecer
la opcin de guardar el informe con la extensin correspondiente al pulsar el botn Guardar (slo valido en
tiempo de ejecucin).

Mostrar un solo registro/ Mostrar ciertos registros

Adems de la posibilidad del Q. Report de mostrar toda la base de datos, hay veces que interesan tan solo
algunos datos almacenados. En estos casos hay tres sistemas: Crear todas las etiquetas (TQRLabel) necesarias
y rellenarlas a mano, crear un informe de toda la tabla, de forma que cada registro ocupe una hoja entera e
imprimir nicamente la hoja que interesa, o usar un componente TQuery. Este componente se utiliza para
ejecutar instrucciones de SQL, y de hecho, eso me propongo, aunque no es exactamente del tema de
Q.Report.
Para empezar creamos un componente TQuery en el mismo formulario donde est el informe. Asignamos su
propiedad DatabaseName a la tabla correspondiente, y en el Q.Report, cambiamos la propiedad DataSet al
TQuickReport
7
TQuery que acabamos de hacer. Despus creamos una variable del tipo que vallamos a seleccionar en la
impresin (si queremos seleccionar un String, la creamos de tipo String). Esto se hace dentro de Parameters,
en el Query. Despus en la propiedad SQL escribimos algo as:

select * from BaseDatos where BaseDatos.Campo =: NombreParametro

Esto le indica que debe seleccionar todos los campos de la BaseDatos mientras que el campo Campo (Que
imaginacin! :-) ) sea igual al parmetro que hemos creado antes (por eso el parmetro debe ser del mismo
tipo que el dato que se busca). Para poner en funcionamiento todo esto escribimos en nuestra unidad:

Query.Active := False;
Query.ParamByName('NombreParametro').AsString := TextoBuscado;
Query.Active := True;
If Query.IsEmpty then ShowMessage (No encontrado);

Con este cdigo seleccionamos los registros en los que el Campo sea igual a TextoBuscado. Aqu hay que
darse cuenta de dos cosas: 1) Primero se cierra el Query, se asigna la bsqueda y se abre. Luego se comprueba
el resultado. 2) Aqu se usa AsString porque buscamos un String, pero hay mas tipos. Pongo a continuacin
los que se pueden usar:

Tipo de datos Correspondencia en Delphi Funcin correspondiente
BCD Currency AsBCD
Blob String AsBlob
Boolean Boolean AsBoolean
Currency Double AsCurrency
Date TDateTime AsDate
DateTime TDateTime AsDateTime
Float Double AsFloat
Integer Integer AsInteger
Memo String AsMemo

Ahora digo que diferencia hay entre mostrar un registro slo o unos pocos: ninguna. Si en el campo slo hay
un dato que coincida con el que buscamos, nada ms coge este. Entonces si buscamos el DNI,
seleccionaremos uno, sin posibilidad de que se repita. Si buscamos un nombre, puede ocurrir que haya ms de
uno, entonces estaremos seleccionando unos pocos registros.
Y slo queda mostrar esto en el informe. Recordar que le habamos indicado al Q.Report que cogiera los
datos del Query. Tambin recordar que le hemos dicho al Query que seleccionara nicamente los registros
que coincidan. Entonces el informe slo mostrar esos, ya que no hay ningn otro registro en el sitio que
busca. Esto se puede ampliar mas, pero entonces tendra que escribir el artculo sobre SQL o InterBase.
Manejando bien este tema, se pueden hacer muchas cosas; yo creo que merece la pena.

Informes Master/Detail

Este tipo de informes es muy importante, ya que es una relacin entre dos tablas. Para explicarlo bien pondr
un ejemplo: Tengo en una tabla los datos de las filiales de una empresa. En los datos est el presupuesto,
nombre, direccin, etc., y un campo con un nmero nico para cada empresa (Es importante que sea nico).
En otra base de datos tengo la lista de empleados con el DNI, sueldo, datos, y un campo que tiene el cdigo de
la empresa en la que trabajan. Un informe Master/Detail creara una lista de las empresas, y entre cada
nombre, intercalara todos los trabajadores de esa empresa, en vez de listarlos aparte. Estos informes son
tiles para dar datos de dos bases distintas pero con una relacin entre ellas.
Antes de empezar aclaro que voy a llamar a la base de datos principal Maestro y a la secundaria Detalles.
Debemos tener dos bases de datos, la Maestra debe tener un campo en la que no se repita ningn valor. Este
campo ser el que relacione. La base Detalles debe tener un campo (con cualquier nombre) del mismo tipo
que la base anterior. Si es distinto no sirve. Aqu s se pueden repetir, y, de hecho, es bastante normal. Los dos
campos que se deben relacionar deben estar en un ndice.
TQuickReport
8
Entro en Delphi. Creamos en un formulario dos componentes de tipo TTable o TQuery, y uno de tipo
TDataSource. A los primeros les llamo Uno y Dos, y al segundo Source. A Uno lo conecto con la tabla
Maestra, y a Dos con Detalles. Despus a Source asigno a la propiedad DataSet el valor Uno (que contiene a
Maestra). Luego cambiamos la propiedad MasterSource de Dos a Source. Para terminar abrimos el dilogo de
la propiedad MasterFields. En la lista Detail Fields aparecen los campos de Detalles que tienen ndice y lo
mismo ocurre en la lista Master Fields, pero con los campos de Maestro en el ndice. Seleccionamos en cada
lista el campo que vamos a unir, pulsamos el botn Add, y ya hemos terminado aqu.
Empezamos con Q.Report. Asignamos su propiedad DataSet a Uno. Creamos bandas, ponemos controles y
cuando ya est esa parte terminada empezamos con la segunda tabla. Creamos un TQRSubDetail, asignamos
DataSet a Dos y Master a QuickReport. En esa banda situamos los controles que muestran los datos de la
segunda tabla. Y ya est. Si hay ms de una banda, puede dar problemas. Para solucionarlos cambie la
propiedad LinkBand de TQRSubDetail para que aparezca el nombre de la banda a la que debe complementar.
Para terminar, resumir todo y ver que fcil es. Creo tres controles, dos de ellos leen los datos, el otro los
conecta. Asigno las propiedades para que sepan que campo les une. Creo el informe, y aado una banda
especial para este tipo de informes. Le aclaro a la banda quin es el jefe y, en caso de problemas le asigno un
lder al que deben seguir :-).
Slo me queda decir que en el nico sitio que se muestran los datos de Dos es en la banda TQRSubDetail.
En caso de que haya ms de una banda de tipo Detail, se debe indicar, como ya he dicho, a cul debe estar
unida.

Expresiones

Dentro de QuickReport hay un sub-lenguaje (digo lo de sub- por su reducido tamao) que puede llegar a ser
bastante complejo y est formado por 21 funciones, 3 variables locales, 3 variables de entorno y todos los
campos de una base de datos. A primera vista no parece mucho, pero se puede usar en varios de los
componentes de Q.Report (TQRExpr, TQRExprMemo y TQRGroup) y tiene muchas opciones. Cualquier
dato que pida una funcin puede sustituirse por otra funcin, e incluso tiene estructura de tipo If.
El fallo ms importante que tiene, es que si no reconoce algo, puede dar un error en una librera. Adems, no
se pueden insertar espacios antes de los nombres, o no los reconoce. Y lo mejor es que si da fallos, suele
indicar donde los da y porqu. Si no hay, devuelve el valor tras efectuar al operaciones y funciones indicadas.
Algunos datos generales: Las cadenas literales se escriben con comillas simples ( ), los tipos que se
manejan son numricos (con o sin decimales), carcter y booleanos, las maysculas y minsculas no se
diferencian (excepto en los literales), la nica estructura disponible es If, se pueden crear y usar cualquier
nmero de variables, tanto locales como globales. A dichas variables no se les pueden asignar valores, pero al
crearlas dan la opcin de asignarlas una expresin, utilizando este lenguaje. Cuando se lea su valor, utilizar
la expresin para proporcionarlo.
Las lneas no se separan con ( ; ). Se pueden leer datos de las tablas, de variables y los resultados de las
funciones. En cualquier momento se puede sustituir valores por variables o funciones, siempre que sean del
tipo requerido. Adems de pueden anidar las funciones y comandos. En textos y ejemplos no dir nada ni
pondr ejemplos de esto, excepto en el apartado correspondiente, sin embargo, se puede hacer siempre. El
nmero mximo de decimales que admite es 13. En caso de que haya ms, se ignoran.
Quiero mostrar antes de empezar dos imgenes para que se vean algunas posibilidades de esto. Presento
primero la imagen de resultado, y despus la ventana de Delphi.


TQuickReport
9



Figura 1
TQuickReport
10
Figura 2

Lo que est escrito en los TQRExpr es:

ExpNombre: Uno.Num + ' : ' + Uno.Nombre
ExpTelefono: 'Telfono : ' + Uno.Tlf
ExpPed1: Dos.Ped1 + ' (' + Dos.Numero + ')'
ExpPed2: Dos.Ped2 + ' (' + Dos.Numero + ')'

Ms adelante veremos qu significa. Por ahora comento las funciones existentes:

Funciones

IF (Exp,Val1,Val2)
Evala la expresin booleana Exp. Si es cierta ejecuta Val1, si no, ejecuta Val2.

IF(PAGENUMBER = 1,Pag1 = TRUE,Pag1 = FALSE)
Si El nmero de pgina es 1, asigna el valor True a Pag1, si no, asigna el valor False a Pag1

STR (Val)
Convierte el nmero Val a String

NUM = STR(1234)
Asigna a la variable NUM (de tipo String) el valor 1234

UPPER(VAL)
Convierte Val a maysculas. No tiene problemas con acentos, s, espacios, comas...
TQuickReport
11

UPPER(HolA)
Convierte a maysculas la cadena HOLA.

LOWER(Val)
Convierte Val a minsculas. Tiene las mismas limitaciones que la funcin Upper

LOWER(HOlA)
Transforma HOLA en hola

PRETTY(Val)
Modifica la cadena Val poniendo la primera letra en mayscula y las otras en minsculas

PRETTY(buenOS Dias)
Devuelve Buenos dias

TIME()
Proporciona la hora actual del sistema (HH:MM:SS) en formato String

DATE()
Retorna la fecha del sistema (DD/MM/AA) en formato String

COPY(Text,Val1,Val2)
Funciona igual que la funcin de Delphi con el mismo nombre. Se usa para coger unos pocos caracteres de
la cadena Text. Empieza en el carcter Val1 (incluido) y coge Val2 caracteres.

COPY('Hola que tal ests',6,7)
Devuelve que tal

MAX (Val)
Devuelve el valor mximo que haya tomado la variable Val.

MIN(VAL)
Establece el valor mnimo que haya tomado Val (generalmente 0 o 1, pero puede cambiar)

AVERAGE(Val)
Calcula la media de los valores que haya tomado la variable Val. Usa 1 decimal.

TRUE, FALSE
Valores booleanos. No tienen parmetros. No devuelven ningn valor. Se usan parecido a Delphi

INT(Val)
Devuelve el valor entero de la variable Val. Se usa igual que TRUNC(Valor). El carcter decimal es el punto
( . ).

INT(8.97)
Devuelve 8

FRAC(Val)
Devuelve el valor fraccionario del numrico Val. El carcter decimal es el punto ( . ). Puede dar algunos
errores (ver los ejemplos)

FRAC(8.9)
Devuelve 0,9

FRAC(8.95)
TQuickReport
12
Devuelve 0,949999999999999 (Quiz podramos solucionar esto en Delphi usando una variable Currency,
pero aqu slo existe la variable Integer, vlida para todos los nmeros)

SQRT(Val)
Calcula la raz cuadrada del nmero Val. Puede usar 13 decimales.

SQRT (6)
Devuelve 2,44948974278318

DIV(Val1,Val2)
Realiza la divisin entera (sin decimales) de Val1 entre Val2. No redondea.

DIV(14,3)
Devuelve 4

TYPEOF(Expr)
Evala la expresion (o variable) Expr y devuelve el tipo de datos (STRING, INTEGER, BOOLEAN)

FORMATNUMERIC(Num,Mask)
Formatea el nmero Num con un string como mscara (ver la ayuda de la VCL para ms informacin,
buscar FormatFloat)


Tambin se usan muchos operadores matemticos. La mayora tambin estn presentes en Delphi y
funcionan muy parecido. Sin embargo, tiene una diferencia importante: el ( = ) se utiliza exclusivamente
como comparador. Las nicas asignaciones que se podran hacer es a las variables, y con stas no se hace
porque utilizan una expresin propia, no un valor fijo. Puede escribirse, en vez de una expresin algo como
esto: 5

As estara asignado este valor, y funcionara como una constante. Pero tambin se podra escribir esto otro:

COPY(BaseDatos.Nombre,1,4)

Entonces s sera una variable, y dependera del campo Nombre en la tabla BaseDatos. Continuar hablando
de las variables, estructuras y posibilidades de todo esto en futuros captulos.
TQuickReport
13


En el presente artculo vamos a hacer un repaso de
los ltimos detalles que parecen de inters a la
hora de generar informes con Quick Report.

En el anterior nmero expliqu las funciones y los signos. Unicamente recordar que el signo igual ( = ) no
sirve para asignar, ya que las variables tienen su propia expresin, que puede ser un valor fijo o depender de
otras variables y/o campos de una tabla.

Expresiones

Este lenguaje, a diferencia de la mayora, nicamente busca mostrar unos datos, que suelen salir de una
tabla o varias, y proporcionrselos al usuario. Como tiene ese objetivo, el resultado final del cdigo que
escribamos no se almacenar en ningn lugar, sino que se muestra en el control.
Por ejemplo: en una tabla tengo un campo booleano, llamado Bool. Si quiero mostrar el contenido en un
informe escribira:

Tabla.Bool

Esto mostrara en el control el texto True. Si quisiera decir Si/No tendra que usar un If:

If (Tabla.Bool, Si, No)

Y si quisiera que apareciera un texto, slo tengo que sumrselo:

Resultado: + If (Tabla.Bool, Si, No)

Para sumar nmeros se hace lo mismo: 5 + 4. Si se quiere sumar un nmero con una variable o dos variables
simplemente se escribe:

4 + NumPag

El texto puede estar en una variable. Aqu hay que utilizar la funcin Str():

Valor: + Str(NumPag)

Variables

Antes de empezar, quiero decir que las variables no existen en las versiones de Q. Report que se distribuyen
con Delphi 3 ni anteriores. En el de Delphi 5 hay dos tipos de variables: las locales, que slo pueden ser
usadas por el control que las cre y las globales, que pueden usarse en todos los controles que admitan este
lenguaje. Las variables no tienen un tipo definido, cualquiera puede almacenar cualquier valor.
En Delphi 5 hay seis variables por defecto. Estas son:

Locales
- PageNumber : Nmero actual de pgina
- ColumnNumber : Nmero de columnas
- ReportTitle : Nombre del informe (Est almacenado en la propiedad Title de TQuickRep)

Globales
- AppStartTime : Hora de inicio de la aplicacin
- AppStartDate : Fecha de inicio de la aplicacin
- AppName : Nombre de la aplicacin
TQuickReport
14

(La fecha y la hora las trata como tipo String.)

Adems de estas se pueden crear ms. En la creacin se pide el nombre y la expresin. Si la expresin
siempre devuelve el mismo valor (5; 8+6; Hola) entonces se pude considerar como una constante. En caso
contrario, se puede escribir una expresin de una sola lnea, que determinar el contenido en el momento en
que se lea.

Al principio dije que haba tres componentes que podan usar este lenguaje. Para usar el TQRExpr
simplemente se modifica su propiedad Expression. El componente TQRExprMemo es una combinacin de
TQRMemo y TQRExpr. Se escribe el texto literal como si fuera en Tmemo, y entre corchetes ( {} ) la
expresin correspondiente, sin hacer referencia a la tabla (P.e: Tabla1.Nombre -> {Nombre} ).

Los TQRGroup es el tercer componente. Estos controles crean los grupos basndose en la expresin
introducida. Cada vez que el resultado de la expresin cambie, se crear un nuevo grupo (P.e: Si se quiere
agrupar los nombres por ndice alfabtico, habra que escribir: Copy(Tabla1.Nombre,0,1) de esta manera,
cuando cambiara la primera letra, los separara de los anteriores).


Unir Informes
La unin de dos o ms reportajes es bastante fcil. Se necesitan tener todos los informes creados y un
componente del tipo TQRCompositeReport. Este tiene una propiedad llamada Reports, que no aparece en la
ventana del inspector de objetos, por lo que slo est disponible en ejecucin. Esta propiedad es del tipo
TList, por lo que tiene la Items, en la cual se deben aadir punteros a los informes que se quieran unir.
Despus se llama al evento Preview y los informes se mostrarn.

Como los informes pueden tener valores distintos en sus propiedades, el componente TQRCompositeReport
tiene las propiedades de tamao de hoja y opciones, adems del nombre del informe resultante. Hay que tener
cuidado, al disear los informes, de que estas propiedades no difieran mucho unas de otras, o podra tener
problemas al visualizar y/o imprimir el resultado.

Para unirlos debe escribir en su evento OnAddReports el nombre de los reportajes que desee unir, en el orden
en que deban aparecer. Por ejemplo:

Procedure Tform1.TQRCompositeAddReports(Sender:Tobject);
Begin
CompositeReport1.Reports.Add(TquickRep1);
CompositeReport1.Reports.Add(TquickRep2);
End;

Y luego podr llamar a TQRCompositeReport.Preview.

Componente TQRChart
El componente TQRChar sirve, igual que su otra versin TCh ar, para mostrar grficos en pantalla. Este
componente est preparado para usarse con TQuickReport, por lo que carece de muchas de las propiedades
de su hemano, ya que se supone que los datos no se conocen en la creacin del informe, y tendr que
aadirse los valores a mano. A pesar de esta carencia, tiene las mismas funciones que el otro, ya que todas
estn incluidas en la propiedad Char, de la que las dos versiones disponen. Para ms informacin en creacin
de grficos y uso de estos componentes, ver los artculos sobre TeeChart que aparecieron en esta revista hace
unos pocos nmeros.

Unin de bandas
Hay veces que se necesita intercalar una banda entre otras dos que van juntas, o unir una banda con otra.
Para hacer esto, hay tres opciones: Incluir los datos a intercalar en la banda en que tenga que ir delante, crear
TQuickReport
15
una banda TQRChildBand, o dejar que lo haga Delphi. Para crearla simplemente se coge de la pestaa
QuickReport, se deja en el informe y se modifica la propiedad ParentBand para indicar a quin debe unirse.
Una vez hecho esto, se unir a la zona inferior de la banda designada. Para que lo cree el ordenador, se elige
la banda a la cual deba unirse, y si tiene la propiedad HasChild, se modifica a True, y ya se crea la banda y se
une sola.

Estas bandas se imprimirn siempre despus de su padre, y cada vez que este aparezca, aparecer la hija.
Una de estas hijas puede tener otra, y esta otra ms, siempre que ninguna de ellas haga referencia a alguna
banda con la que ya tuviera relacin. As, se pueden tener cinco hijas unidas unas con otras, pero la primera
no se podra unir con la tercera, ya que, indirectamente, se encuentran unidas. Dara un error y deshara el
vnculo.

También podría gustarte