PDA

Ver la Versión Completa : QuickReport - Seleccionar bandeja


alapaco
01-09-2006, 22:05:19
Tengo problemas para mandar un reporte hecho con quickreport a una bandeja determinada.

El tema es asi: yo tengo un reporte y los usuarios tienen que poder elegir si imprimirlo por la bandeja 2 o por la bandeja 3 (por ejemplo).

Probé cambiar la propiedad PrinterSettings.CustomBinCode pero ignora eso y sigue imprimiendo en la bandeja que está configurada por default.

Uso la version 3.6.2 de QR y estoy tratando de imprimir en una HP Laserjet 4100, aunque tambien pasa en otros modelos de HP.

Alguien tienen alguna idea de que puede estar sucediendo ??

Gracias desde ya.

Caral
01-09-2006, 22:21:05
Hola
Yo normalmente llamo al reporte por medio de un form en el que especifico los factores que quiero que se vean, con esto practicamente con el mismo formulario de Qreport hago varios reportes diferentes.
este es un codigo que utilizo para llamar a un reporte (X) desde este form.

If Reporte = 'ComprasXProveedor' then
begin
ShortDateFormat := '#yyyy/mm/dd#';
try
QRComprasXCliente:=TQRComprasXCliente.Create(self);
QRComprasXCliente.ADOQuery1.SQL.Add(' WHERE CxPagar.TipoTransac="FA" ');
QRComprasXCliente.ADOQuery1.SQL.Add(' AND FechaTransac >= '+DateToStr(DTP1.Date)+' AND FechaTransac <= '+DateToStr(DTP2.Date));
QRComprasXCliente.ADOQuery1.SQL.Add(' AND Proveedores.CodProve >= '+Edit3.Text+' AND Proveedores.CodProve <= '+Edit4.Text);
QRComprasXCliente.ADOQuery1.SQL.Add(' ORDER BY CodProveedor, FechaTransac;');
QRComprasXCliente.ADOQuery1.Open;
ShortDateFormat := 'dd/mm/yyyy';
QRComprasXCliente.Titulo.text := 'Compras Realizadas a Proveedores';
QRComprasXCliente.QRLblDesde.Caption := DateToStr(DTP1.Date);
QRComprasXCliente.QRLblHasta.Caption := DateToStr(DTP2.Date);
If RadioGroup1.ItemIndex = 0 then QRComprasXCliente.Print
else QRComprasXCliente.Preview;
finally
QRComprasXCliente.Free;

con esto se presenta un pre- reporte en pantalla y escojo la impresora en la que quiero imprimir, siempre que voy a cambiar de impresora, indico que me lo muestre por pantalla antes, de lo contrario me lo envia a la inpresora predeterminada.
espero te sirva
Saludos

alapaco
01-09-2006, 22:32:42
Si por supuesto, pero yo pregunto sobre la posiblidad de seleccionar la bandeja en la que quiero que salga mi reporte.

No sobre como se hace un reporte en si.

Gracias de todas formas.

jlmelida
03-09-2006, 10:30:44
Hola:
Yo siempre he creido que los desarrolladores de quickreport gastaron toda su materia gris en programar y no les quedó nada para documentarlo. En otras palabras: Es uno de los mejores generadores de reports pero sin duda, es el peor explicado de todos.

Como para casi todo con quickreport, te van ha hacer falta los fuentes ( o sea la versión profesional).

Si cargas QrPrntr verás como esta definida la clase TPrinterSettings, que es la que te permite definir las caracteríticas últimas de la impresion: tipo de papel, orientación y por supuesto la bandeja.


El procedure GBin es el encargado de seleccionar la badeja de la impresora:






procedure GBin; { Paper bin }
var
aBin : integer;
I : TQRBin;

begin
FOutputBin := First; // default

if Supported(dm_defaultsource) then
begin

aBin := DevMode^.dmDefaultSource;

for I := First to Last do

if cQRBinTranslate[i] = aBin then
begin

FOutputBin := I;
exit;
end;

end;
end;




Como ves, este procedimiento encargado de seleccionar la bandeja de la impresora, es bastante oscuro.

Deberemos hacer un pequeño programa que nos diga los numeros ( fijate que aBin es un integer) de las bandejas de nuestra impresora, para poder seleccionarlas por programa. Lo dejo para otra entrega.

Saludos

jlmelida
03-09-2006, 11:13:15
Para comprender mejor como funciona
la selección de la bandeja, vamos a
desarrollar una pequeña aplicación.
Cargas Delphi, e inicias un nuevo proyecto.
Le llamaremos Eligebandejas

Nuetro proyecto tendrá por ahora una sola unidad.
El nombre se lo pones a tu gusto, que sea algo
original y nunca visto antes,
como por ejemplo Mainform.:)

Nuestra unidad tendrá aparte del form,
dos speedbuttons, una etiqueta y un
PrinterSetupDialog. El caption del
primer boton será 'Printer Setup'.
El caption de la etiqueta será 'Bin Code'
( que es lo que queremos conocer).
El otro boton, de momento lo dejamos inutil.

Al terminar el codigo debe quedar así:



Código Delphi [-] (http://www.clubdelphi.com/foros/#) Código Delphi [-] (http://www.clubdelphi.com/foros/#)
unit MainForm;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, StdCtrls;
type
TForm1 = class(TForm)
SpeedButton1: TSpeedButton;
Setup1: TPrinterSetupDialog;
Label1: TLabel;
SpeedButton2: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
UserBinCode : integer;
UserCollateCode : integer;
implementation
uses printers;
{$R *.DFM}
// Esta función devuelve el codigo de bandeja
// seleccionado por el usuaro.
// Puede adaptarse facilmente para conocer
// otros miembros de DevMode
/ como collate, print quality etc
// Se usan variables globales para
//poder recuperar otros parámetros
// Ver 'UserCollateCode' .

function GetBinSelection: integer;
var
hDevMode: THandle;
Device,Driver,Port: array [0..1024] of Char;
bin: integer;
DevMode : PDevMode;
begin
Printer.GetPrinter (Device,Driver,Port,hDevMode);
bin := -1;
if hDevMode <> 0 then
begin
DevMode := GlobalLock (hDevMode);
//aqui podemos capturar los mienbros de DevMode
bin := DevMode^.DMDEFAULTSOURCE;
UserCollateCode := DevMode^.dmCollate;
GlobalUnlock (hDevMode);
end;
result := bin;
end;

{ En el evento on click del primer boton
lanzamos el dialogo del driver de laimpresora. En este
elegimos la bandeja que queramos.
Al cerrar el dialogo, llamamos a la funcion GetNinSelection
que nos devolverá el numero de la bandeja. Tambien usando variables globales, podemos devolver otros miembros de DevMode. Lo importante, es que sabremos
los numeros de la bandeja de nuestra impresora y los podremos usar posteriormente }


procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
setup1.Execute;
UserBinCode := GetBinSelection;
label1.Caption := 'Bin code : ' + inttostr( UserBinCode)+ ' Collate code ' + inttostr( UserCollateCode);
end;







Compila el proyecto y ejecutalo con tu impresora. Apunta lso codigos de cada bandeja.
Saludos

jlmelida
03-09-2006, 12:29:41
Añadamos una segunda unidad, que será un report para ver como funciona la elección de bandeja. Este report será lanzado por el segundo botón de la unidad principal. Así pues, lo primero es escribir algo en el caption del segundo boton: Pondremos 'Print' y el eventon on click se encargará de lanzar el report. En resumen, la unidad principal quedá así:


[/URL]

unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, StdCtrls;
type
TForm1 = class(TForm)
SpeedButton1: TSpeedButton;
Setup1: TPrinterSetupDialog;
Label1: TLabel;
SpeedButton2: TSpeedButton;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
UserBinCode : integer;
UserCollateCode : integer;
implementation
uses printers, miReport; { MiReport es el originalisimo nombre de la segunda unidad}
{$R *.DFM}

function GetBinSelection: integer;
var
hDevMode: THandle;
Device,Driver,Port: array [0..1024] of Char;
bin: integer;
DevMode : PDevMode;
begin
Printer.GetPrinter (Device,Driver,Port,hDevMode);
bin := -1;
if hDevMode <> 0 then
begin
DevMode := GlobalLock (hDevMode);

bin := DevMode^.DMDEFAULTSOURCE;
UserCollateCode := DevMode^.dmCollate;
GlobalUnlock (hDevMode);
end;
result := bin;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
setup1.Execute;
UserBinCode := GetBinSelection;
label1.Caption := 'Bin code : ' + inttostr( UserBinCode)+ ' Collate code ' + inttostr( UserCollateCode);
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
report1.quickrep1.print;
end;







La segunda unidad tendrá un quickreport. La propiedad bands de este será todas false menos HasDetail y HasPage Header

En la banda de cabecera pondremos un TQRLabel y en el caption algo descriptivo como: 'Prueba de selección de bandeja'
En la banda de detalles colocamos otro TQRLabel para que veamos como queda el report

El codigo quedará así


[URL="http://www.clubdelphi.com/foros/#"] (http://www.clubdelphi.com/foros/#)unit MiReport;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
QuickRpt, QRCtrls, ExtCtrls;
type
Treport1 = class(TForm)
QuickRep1: TQuickRep;
PageHeaderBand1: TQRBand;
DetailBand1: TQRBand;
QRLabel1: TQRLabel;
QRLabel2: TQRLabel;
procedure QuickRep1NeedData(Sender: TObject; var MoreData: Boolean);
procedure QuickRep1ApplyPrinterSettings(Sender: TObject;
var Cancel: Boolean; DevMode: Pointer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
report1: Treport1;
lineno : integer;
implementation
uses MainForm;
{$R *.DFM}
procedure Treport1.QuickRep1NeedData(Sender: TObject; var MoreData: Boolean);
begin
// Escribimos el interesantismo report qrlabel1.caption := 'Linea ' + inttostr( Lineno);
inc(lineno);
MoreData := lineno < 30;
end;

procedure Treport1.QuickRep1ApplyPrinterSettings(Sender: TObject;
var Cancel: Boolean; DevMode: Pointer);
begin
// Sobreescribimos la función con nuestros parametros
// Podemos alterar muchas cosas:
// DevMode^.dmPrintQuality := PrintQuality;
// DevMode^.dmCollate := Collate;
// DevMode^.dmColor := ColorOption;
// Por supuesto la orientación, tamaño, etc.

PDevMode(DevMode).dmDefaultSource := UserBinCode;
PDevMode(DevMode).dmCollate := UserCollateCode;
end;
end.




En fin, espero haber respondido a lo que planteabas.
Saludos

alapaco
04-09-2006, 15:40:24
Te agradezco mucho el tiempo que te has tomado, pero a pesar de elegir la bandeja 3, el reporte sigue saliendo en la bandeja 2 (que es la que tiene el papel que tiene seteado el QR).

Alguna otra solución ?

jlmelida
04-09-2006, 19:55:35
Te agradezco mucho el tiempo que te has tomado, pero a pesar de elegir la bandeja 3, el reporte sigue saliendo en la bandeja 2 (que es la que tiene el papel que tiene seteado el QR).

Alguna otra solución ?

Puede ser, tratandose de una HP, que la tengas configurada por Menu para que haga precisamente eso. Lo digo porque en nuestro trabajo tenemos una LaserJect 3800 Color que nos dio bastante trabajo hasta que conseguimos que hiciese lo que tenía que hacer. Si no la configuramos adecuadamente, prevalece lo que le manda su configuración ignorando todo lo que le envíe el sofware.
Para comprobar si eso es asi, lo mejor es que imprimas dede el word, cambiando la bandeja a ver si obedece.

Por último decirte que lo anterior solo trabaja para las versiones de qreport
362. Si usas alguna anterior debes modificar el codigo de TPrinterSetting.ApplySetting en el QRPrntr.pas.

Si fuese así dímelo y te lo envío

Saludos.

alapaco
04-09-2006, 19:59:07
Nuevamente muchas gracias, por a probarlo y te cuento como me fue.

hogol
06-11-2006, 11:24:54
Hola buenas

Quería preguntar si se podría conseguir el mismo resultado sin necesidad de tener instalado el quickrep pro.
He probado a instalarlo y el ejemplo funciona perfectamente, pero el quickrep me provoca errores de incompatiblidad con los componentes teechart y al final la cosa me causa más problemas que soluciones, de ahí mi pregunta.

En todo caso, gracias por la ayuda :)