PDA

Ver la Versión Completa : Duda con el Qreport.


chele
22-03-2004, 13:07:53
Buenas, os comento a ver si me sabeis decir que puedo hacer o que hago mal.

Tengo dos form, uno donde hago una seleccion de datos segun valores uqe me meten y otra donde tengo el Qreport.

En el de seleccion de datos tengo esto :

procedure TListadosCasosAbiertos.Button1Click(Sender: TObject);
var cadenaSQL : string;
qry : tIBQUERY;
begin

cadenaSQL := 'select refcomp, expedientes.codexp from expedientes inner join resumenpagos on resumenpagos.codexp=expedientes.codexp';

qry := TIBQuery.Create(qry);
qry.database := datamodule2.database;
Qry.SQL.Text := cadenaSQL;
qry.open();

CHlistadoAbiertoImpr.QuickRep1.DataSet :=qry;
CHlistadoAbiertoImpr.QuickRep1.Preview;


end;


Con esto abro el del listado pero claro esta no picha ningun valor.

¿Como le digo que el TQRDBText que se llama nombre debe llevar un valor del sql ... ¿Como se haria eso?.

¿Esta mal planteado?.

Venga un saludo y gracias anticipadas XD

__cadetill
22-03-2004, 13:39:57
¿Como le digo que el TQRDBText que se llama nombre debe llevar un valor del sql ... ¿Como se haria eso?.
Puedes hacerlo en diseño mediante la propiedad DataField del componente

chele
22-03-2004, 18:01:05
Si pero es que en diseño no puedo, ya que le meto el codigo yo escrito y hasta que no se ejecuta no se crea para poder ponerlo en el datafield. ¿me explico?

__cadetill
22-03-2004, 18:24:08
aunque no tengas los campos persistentes en la Query, si siempre devuelve las mismas columnas, puedes escribir tu "a mano" el nombre del campo que quieras visualizar en él

chele
23-03-2004, 11:02:56
Ok,he probado como comentas, puse esto :

procedure TListadosCasosAbiertos.Button1Click(Sender: TObject);
var cadenaSQL : string;
impresion1: tIBQUERY;
qry: tIBQUERY;
begin

cadenaSQL := 'select refcomp as referencia, expedientes.codexp as codexpediente from expedientes inner join resumenpagos on resumenpagos.codexp=expedientes.codexp';

qry := TIBQuery.Create(qry);
qry.database := datamodule2.database;
Qry.SQL.Text := cadenaSQL;
qry.open();

CHlistadoAbiertoImpr.QuickRep1.DataSet := qry;
CHlistadoAbiertoImpr.QRDBText1.DataSet :=qry;
CHlistadoAbiertoImpr.QRDBText1.DataField := qry.fieldbyname('referencia').value;
CHlistadoAbiertoImpr.QuickRep1.Preview;

end;


Y me muestra las dos lineas ( es decir picha bien los datos ) pero en el TQRDBtext no me muestra ningun valor.

¿Que hago mal?.

Gracias anticipadas.

Lepe
23-03-2004, 12:10:33
Si estas intentando hacer listados personalizados....
Yo he usado la función QRCreateList de la unidad qrExtra.

En la ayuda de quickReports viene un ejemplo con el que empezar.

Con esta opcion, le envias el dataset del que provienen los datos y un TstringList con el nombre de los campos que quieres visualizar, y crea el listado automaticamente, despues de generado el informe, puedes recorrerlo para cambiar ciertos detalles como el pié de pagina (para ponerlo en español), etc...

Hay un detalle que se puede corregir, Cuando creas el listado, el ancho de cada columna lo coge de la propiedad DisplayWidth del Tfield, se puede cambiar esa propiedad en tiempo de ejecución (antes de lanzar el listado) para que el ancho de cada columna se ajuste al texto que se va a imprimir.

Pruebalo, y si te interesa, posteo mi funcion AjustaDisplayWidth

Saludos

__cadetill
23-03-2004, 12:18:36
CHlistadoAbiertoImpr.QRDBText1.DataField := qry.fieldbyname('referencia').value;
Es que no es el Value lo que has de asignar, sino "referencia" directamente, es decir, el nombre del campo.

Pero sigo diciendo que lo puedes asignar en diseño, no en ejecución si la query retorna siempre los mismos campos.

Por otro lado, Lepe yo sí estaría interesado en ver como haces eso, me ha gustado el tema este del QRCreateList :p

chele
23-03-2004, 12:25:40
Referencia ... te cagas ahora funciona.

ES decir tengo que asignarle el nombre que le he puesto en la tabla.

Vale ahora si te entiendo, claro yo le meto el sql y ahi ya le envio los valores, joder que torpe soy a veces XD

Gracias muchas gracias ya me funciona, ahora a seguir investigando.

__cadetill
23-03-2004, 12:58:08
Siguiendo con el tema del QRCreateList, en la página de QuSoft hay una demo. Os dejo la URL (http://www.qusoft.com/stanlegacy.html)

MODIFICACION: si os descargais esta demo, tener en cuenta que en versiones posteriores a la de Delphi para la que fué diseñado (1..3) cambian el tipo de los parámetros (en lugar de un TQuickReport hay que pasar un TCustomQuickReport). Esto conlleva cambiar el tipo de la variable y tener que hacer algún que otro casteo para que funcione la demo en versiones posteriores de Delphi (como la 6 que es en la que yo lo he probado)

Lepe
23-03-2004, 17:50:52
Bueno, aqui va una de código, ahh, si quereis optimizar el código... será bienvenido :D

Uso una funcion rarita... codigoutil.ifthen es la equivalente que tiene Delphi en la unidad Math, strutils, y en otra unidad más que no recuerdo, yo las he metido en un .pas llamado CodigoUtil .... muy original .... ya :)

Las Lineas que empiezan con FrmDebug.anade ... son llamadas a una ventana auxiliar para ver por donde iba el programa y como furulaba. (pueden obviarse esas lineas.


procedure AjustaDisplayWidth(D:TDataSet;const MaxAncho:Integer = 150);
var i, nIdx:Integer;
begin
if D.Active then
begin
try
D.DisableControls;
D.First;
nIdx:=0;
while not D.Eof do
begin
for i:=0 to pred(D.FieldCount) do
begin
// en la 1ª vuelta reseteo el displayWidth existente
if (nIdx = 0) then
D.Fields[i].DisplayWidth := 1;
D.Fields[i].DisplayWidth :=EnsureRange(
Max( D.Fields[i].DisplayWidth,
Length(D.Fields[i].AsString)+
codigoutil.IfThen(D.Fields[i].DataType = ftFloat, 3)
// añadimos espacios para ,00
),
0,MaxAncho);
end;
D.Next;
Inc(nIdx);
end;
finally
D.EnableControls;
end;
end; // D.active
end;


Formatear los números para que salgan en los listados con 2 decimales y puntos de millar:

procedure FormatFloatFields(Rpt:TcustomQuickrep);
var j :Integer;
Band : TQRcustomBand;
begin
Band := Rpt.Bands.DetailBand;

for j:=0 to Band.ControlCount -1 do
if Band.Controls[j] is TQRExpr then
with TQRExpr(Band.Controls[j]) do
begin
if (Pos('percentiva',Expression) = 0)) then
Mask := '#,##0.00'; // curosamente si es un texto lo que hay no le
// afecta, solo he probado con campos de
// Float, Texto, Boolean y enteros. con los demás no
// sé que hará exactamente.
end;
end;

Añadir un SummaryBand en tiempo de ejecución (despues de la linea del QrcreateList) Esta funcion es un coñazo.... no está muy bien hecha :(. Además he encontrado algunos bugs menores que no sé como solucionarlos.


procedure AnadirSummaryBand(Rpt:TcustomQuickrep;const Data : TDataSet;const Campos:TStringList);

const SEP = 20;

var i :Integer;
MaxLeft : Integer;
CampoActual: TField;
TotalLabel : TQRLabel;
Total : TQRExpr;
Unidades: TQRUnit;
begin
// 9-03-2004 añadir totales al informe
with Rpt do
begin
Unidades:= units;
Units := Pixels;
if not Bands.HasSummary then
begin
Bands.HasSummary:= True;
with Bands.SummaryBand do
begin
Height:= 50;
Frame.DrawTop:= True;
Frame.DrawBottom:= True;

// El texto puede salirse a la dcha de la linea right
// Frame.DrawLeft:= True;
// Frame.DrawRight:= True;
end;
end;
MaxLeft:=0;
for i:=0 to pred(Campos.Count) do
begin
CampoActual := Data.FindField(Campos[i]);
if CampoActual <> nil then
if CampoActual.DataType = ftfloat then
begin
if CampoActual.FieldName= 'percentiva' then
Continue;

TotalLabel := TQRLabel(Rpt.Bands.SummaryBand.AddPrintable(TQRLabel));
TotalLabel.Top:= 10;
TotalLabel.AutoSize:= True;
TotalLabel.Caption:= LeftStr(CampoActual.DisplayLabel,10)+':';
// Base Imponible se solapa con el siguiente campo que haya
totallabel.Frame.DrawBottom:= True;
// frmDebug.Anade(['left antes', 'maxleft '],[TotalLabel.Left, MaxLeft] );
TotalLabel.Left:= MaxLeft;

total := TQRExpr(Bands.SummaryBand.AddPrintable(TQRExpr));
total.Top:= 30;
Total.AutoSize:= True;
total.Expression:= 'SUM('+ CampoActual.FieldName+')';
Total.Left:= TotalLabel.Left;
Total.Mask:= '#,##0.00';
MaxLeft := Max(Total.Width, TotalLabel.Width)+ MaxLeft+SEP;

// frmDebug.Anade('pagina' + FloatToStr(Rpt.Page.Width)+' maxleft '+IntToStr(MaxLeft));

if (Rpt.Page.Orientation = poportrait) and (MaxLeft >Rpt.Page.Width) then
Rpt.Page.Orientation:= poLandscape;
end;
end;
end;
// fin 9-03-2004 añadir totales al informe

Rpt.Units:= Unidades;
end;


Cambiar el número de pagina poniendolo en español, despues de la linea del qrcreatelist

with TQRExpr(V.pQuickreport.Bands.PageFooterBand.Controls[0]) do
expression := QuotedStr('Página ') +'+ PAGENUMBER';
// PAGENUMBER es una variable que entiende QUICKREPORTS


La forma correcta de llamarlo sería asÍ:


V:= TPrevi.Create(FrmMdi );
FreeAndNil(V.pquickreport);
qrextra.QRCreateList(tcustomquickrep(V.pQuickreport),v, DTM.qryAlb,
TituloListado ,ListaCampos);

AjustaDisplayWidth(dtm.qryalb);
AnadirSummaryBand(V.pQickReport,dtm.qryAlb,ListaCampos);
FormatFloatFields(V.pQuickReport);


with TQRExpr(V.pQuickreport.Bands.PageFooterBand.Controls[0]) do
expression := QuotedStr('Página ') +'+ PAGENUMBER';
// PAGENUMBER es una variable que entiende QUICKREPORTS
V.pQuickreport.units:= MM;
V.pQuickreport.OnPreview:= ListadoOnPreview;


Los Uses que os puede pedir son estos:

uses nkstrs,Forms,strutils, Windows,Graphics,Registry,dbtables, Classes,
types, sysutils,DB, dbgrids, math ,Variants,
QuickRpt,QRCTRLS, qrprntr, Controls,qrexpr,printers // anadirSummaryband


Espero no olvidarme de nada... Aunque no lo juro, ha sido copy y paste.

Cadetill: ojo al TPrevi.Create :D

Buen Provecho.

Lepe
24-03-2004, 02:24:37
Siguiendo con el tema del QRCreateList, en la página de QuSoft hay una demo. Os dejo la URL


Bonito ejemplo :p :p

PD: Hace un par de semanas me habría venido de perlas ese enlace :p

yusnerqui
29-09-2004, 15:01:58
Desido reabrir este magnífico hilo ya que me ha serbido de mucho en mi actual aplicación.

Pero me quedé trabado despues de bajar de la página de el amigo Cadetill ese maravilloso componente del que tanto se ha hablado en el club e intentar visualizar mi reporte (creado con QRCreatelist) no me lo visualiza correctamente.

Mi pregunta es:

Que debo implementar el el procedimiento ListadoOnPreview :confused:



V.pQuickreport.OnPreview:= ListadoOnPreview;



De antemanos mil gracias

Un saludo a todos ;)

Lepe
30-09-2004, 09:12:15
Todo un honor que se reabra un hilo en el que he participado.

como todo... hay varias formas de hacerlo, en su momento, y con prisas yo opté por hacerla de esta forma.


var :Tprevi;
implementation
procedure botonClick(...)
begin
try
// introduzco en ListaCAmpos(stringlist) los campos que quiero que se vean de la tabla, despues

v:= TPrevi.Create(FrmMdi);
FreeAndNil(v.pquickreport);
qrextra.QRCreateList(tcustomquickrep(v.pQuickreport) ,v , DTM.qryClientes,
'Clientes' ,ListaCampos);

with TQRExpr(v.pQuickreport.Bands.PageFooterBand.Controls[0]) do
expression := QuotedStr('Pág. ') +'+ PAGENUMBER ';
// PAGENUMBER es una variable que entiende QUICKREPORTS


v.pQuickreport.OnPreview:= ListadoOnPreview;
v.pQuickreport.PreviewModal;//eless ;

finally
ListaCampos.Free;
end;


procedure tfrmclientes.ListadoOnPreview(Sender:TObject);
begin
// en el evento Onpreview del TQuickRep
// creado el previ al dar al boton imprimir
with v do
begin
Caption := Caption + ' - Clientes';
// pQuickReport := TQuickRep(Previ.pQuickreport);
Preview.QRPrinter := TQRPrinter(Sender);
pQuickreport.ReportTitle:= ' Clientes';
pQuickreport.Font.Name:= 'Courier New';
Show; // no uso preview, para que pueda continuar haciendo otras cosas
end;
end;

yusnerqui
30-09-2004, 16:40:25
Muchas gracias Lepe, poco después de postear encontré la solución. A propósito a continuación vioy a mostrar lo que hago para configurar la página del reporte en tiempo de ejecución, me funciona bien en Windows 98 no lo he probado en otros sistemas operativos

procedure TReport.Vistaprevia;
var
Title:string;
I : Integer;
begin
Previ := TPrevi.Create(Self);
//Creo el pQuickreport y cambio sus propiedades a gusto del usuario!!
Previ.pQuickreport := TQuickRep.Create(Previ);
with Previ.pQuickreport do
begin
Page.Units := MM;
Page.PaperSize := Custom;
Page.Width := 420.0;//Puede ser un valor definido por el usuario
Page.Length := 270.0;// " "
end;


Title:=Edit1.Text;

try
if Campos1.items.Count >0 then
begin
QRCreatelist(TCustomQuickRep(Previ.pQuickreport),Previ,RTabla,Title,Campos1.Items);
try
with Previ.pQuickreport do
begin
with Bands.ColumnHeaderBand do
begin
Font.Size := 12;
Font.Style:= [fsBold];
Frame.DrawBottom := True;
for i := 0 to ControlCount -1 do
if Controls[i] is TQRLabel then
TQRLabel(Controls[i]).Frame.DrawBottom := False;
end;
with Bands.DetailBand do
begin
Font.Size := 12;
//aquí capturo los campos boolean para redireccionar su evento
//onPrint y no me imprima True y False sino los caracteres que yo
//espesifique
for i := 0 to ControlCount -1 do
if Controls[i] is TQRExpr then
begin
Title := TQRExpr(Controls[i]).Expression;
Title := Copy(Title,2,Length(Title)-2);
if ord(RTabla.FieldByName(Title).DataType) = 5 then
begin
TQRExpr(Controls[i]).Alignment := taCenter;
TQRExpr(Controls[i]).OnPrint:= MyOnPrint;
end;
end;
end;
Previ.pQuickreport.OnPreview:= MyPreview;
Previ.pQuickreport.Preview;
end;
finally
//
end;
end;
finally
//
end ;




Este código está en fase de depuración, ahora la impementación de MyPreview


procedure TReport.MyPreview(Sender : TObject);
begin
with Previ do
begin
Preview.QRPrinter := TQRPrinter(Sender);
Show;
end;
end;


Por último, no me preocupo por el ancho de las columnas pues lo primero que hago es mostrar los campos seleccionados en un DBgrid donde el usuario puede ajustar el ancho de cada campo a su antojo
y es todo, espero que a alguien le sirva si lo que quiere es configurar página, márgenes etc les ser virá esta idea.

Un saludo