PDA

Ver la Versión Completa : Imprimir facturas desde dbgrid.


Tauro78
28-01-2007, 19:36:01
hola, estoy haciendo un programa de facturacion con Delphi7 y quisiera saber lo siguiente:
tengo una pantalla con un dbgrid y demas en la cual el usuario genera la factura (con su detalle), debo decir que la factura ya esta diseñada en el papel en el cual se va a imprimir (adjunta en factura.jpg), el ancho de la factura es la de una hoja A4, pero el alto de cada factura es de 17 cm aprox. y para algunos casos se deben imprimir 3 copias de una misma factura para lo cual el usuario deberia poder elegir el numero de copias a imprimir.
entonces segun creo puedo hacer:

1) desde el form por medio de un boton (Imprimir) pasar los datos directamente desde la forma a la impresora, como lo puedo hacer? ya que deberia colocar cada dato en el espacio que debe ocupar en la factura. Ademas como haria para poner como parametro el numero de copias a imprimir? Y tambien deberia de tener definido el tamaño del papel (21X17) para que lo tome la impresora?

2) desde el form por medio de un botón llamar a QReport o Rave y de alguna manera ajustar el tamaño de la hoja y hacer que se vea el reporte como si fuera la factura, pero al momento de imprimir solo me imprimira los datos ya que lo demás ya esta diseñado en el papel de impresión.

Creo que la opcion 2 no me parece dificil de realizar, pero mi jefe prefiere
la opcion 1, ya que elige el numero de copias le da a imprimir y nada más.

Gracias anticipadas.

marcoszorrilla
28-01-2007, 19:39:13
La opción correcta es la 2, al menos con QuickReport puedes decirle el número de copias que deseas. (En PrinterSettings, tienes la opción Copies:xx),

Un Saludo.

Tauro78
28-01-2007, 19:45:46
Yo pienso lo mismo, pero mi jefe prefiere la opcion 1, entonces me gustaria saber cual seria la forma de llevarla a cabo. Supongo que tendria que recorrer por fila y columna, pero por ahora no me ha salido mucho. Muchas gracias.

marcoszorrilla
28-01-2007, 19:54:48
La opción 1 no la he citado porque eso supondría imprimir con el Canvas de la impresora lo cual resulta harto complicado cuando además habrá que alinear números por la derecha etc...

Mira un extracto para que te hagas una idea del problema:


procedure ImpAlba(n:Integer);
var
nSaltLin:Integer;
nSaltPun:Integer;
nLinea:Integer;
lEuro:Boolean;
cCadena:String;
begin
//1 Albarán en Euros
nSaltLin:=0;

DmXXXX.Cli.IndexName:='Codigos'; //Para poder buscar quien es el cliente.
DmXXXX.Cli.FindKey([DmXXXX.AlbaCodCliente.Value]);

SetPaperSize(DmXXXX.ConfAltoAlbaran.Value,DmXXXX.ConfAnchoAlbaran.Value);
Printer.Canvas.Font.Size:=DmXXXX.ConfFontSizeEncabezado.value;
Printer.Canvas.Font.Name:=DmXXXX.ConfFontEncabezado.Value;


With Printer.canvas do
Begin

printer.BeginDoc;
HeadIMpalba(1);
//Datos del Detalle del Alabarán
Printer.Canvas.Font.Size:=DmXXXX.ConfFontSizeDetalle.value;
Printer.Canvas.Font.Name:=DmXXXX.ConfFontDetalle.Value;

DmXXXX.Linalba.First;
nSaltLin:=0;
nSaltPun:=DmXXXX.ConfASaltoLinea.Value;
While Not DmXXXX.LinAlba.Eof do
begin
nLinea:=nLinea + 1; //control de número de líneas por albarán

if nLinea > DmXXXX.ConfASaltoPagina.Value then
begin
Textout(DmXXXX.ConfAcolDescripcion.value,DmXXXX.ConfAlinNArticulo.Value + (nSaltLin * nSaltPun) ,'..........');
nLinea:=0;
nSaltLin:=0;
Printer.NewPage;
HeadImpalba(1);
end;



cCadena:=numero2Texto(DmXXXX.AlbaRecargo1.Value,2,7);
Textout(DmXXXX.ConfAcolRecTtl.value ,DmXXXX.ConfAlinBase.Value + (nSaltLin * nSaltPun) , cCadena);

end;
nSaltLin:= nSaltLin + 1;
end;


//Ver si tiene recargo 1
if DmXXXX.AlbaRecargo3.Value <> 0 then
begin
cCadena:=numero2Texto(DmXXXX.AlbaTRec3.Value,2,5);
Textout(DmXXXX.ConfAcolRec100.value ,DmXXXX.ConfAlinBase.Value + (nSaltLin * nSaltPun) , cCadena);
cCadena:=numero2Texto(DmXXXX.AlbaRecargo3.Value,2,7);
Textout(DmXXXX.ConfAcolRecTtl.value ,DmXXXX.ConfAlinBase.Value + (nSaltLin * nSaltPun) , cCadena);
end;
nSaltLin:= nSaltLin + 1;
end;

//Pesetas en posición fija
cCadena:=numero2Texto(DmXXXX.AlbaETotal.Value,0,11);
//Se quitan las pesetas 01-04-04 Laura
//Textout(DmXXXX.ConfAcolEuros.value ,DmXXXX.ConfAlinEuros.Value , cCadena);

Printer.EndDoc;
end;
end;


Esto con un Constructor de informes sin embargo es pan comido.

Un Saludo.

Tauro78
29-01-2007, 16:15:27
hola tengo unas preguntas; los distintos valores (Ancho, Alto, Fuente, SaltoPagina) del documento a imprimir los tenes definidos en la tabla Albaranes junto con los demas datos del albaran ?

Para que sirve el procedimiento numero2Texto, tu lo crastes ?

En donde le das la ubicacion que deben tener los datos en el documento ?

Con esto no necesitas definir el tamaño del papel en las impresora ?

Disculpa las preguntas, estoy tratando de entender tu ejemplo para aplicarlo a mi caso, muchas gracias.

Lepe
29-01-2007, 16:28:11
¿no estamos complicando la cosa?

Edito: Acabo de leer de nuevo el mensaje y parace que no quiere usar QuickReport... y ¿reportman que es gratuito?

- Diseñas un Quickreport (en tiempo de diseño) con qrdbtext justo donde deben ir para que cada dato salga en su casilla.

- El tema de papel, mejor te olvidas, usa un A4 y un pié de página de 12 cm. (29 cm que tiene el folio menos 17 cm que ocupa la factura). Listo, en cada folio va una factura.

- El quickreport tendrá como origen de datos una consulta, por ejemplo parametrizada, es decir que le puedas decir que imprima la factura nº 321.

- El botón sobre tu ventana, hará algo similar a esto:

var qr : Tquickreport1;
begin
qr := Tquickreport1.Create(self);
query1.parambyname('nFactura').AsXXXX := 'el número de factura a imprimir';
query1.Open;
qr.print;


Como ves, el botón crea el quickreport, abre la consulta donde estaran los datos a imprimir, y por último, imprime directamente sin mostrar la presentación en pantalla.

Podrías usar un TDialogPrinter para pedir el número de copias a imprimir.

Saludos

marcoszorrilla
29-01-2007, 16:31:10
Los valores que comentas los tengo guardados en una tabla llamada configuración, ello permite cambiar la ubicación de cualquier dato.
También le paso el tamaño de papel antes de comenzar a escribir.

Para el tamaño de papel utilizo la función del API:


procedure SetPaperSize (intAlto,intAncho : Integer);
{aqui se define el tamaño del papel}
var
ADevice, ADriver, APort : array [0..255] of Char;
ADeviceMode : THandle;
DevMode : PDevMode;
begin
with Printer do
begin
GetPrinter (ADevice, ADriver, APort, ADeviceMode);
SetPrinter (ADevice, ADriver, APort, 0);
GetPrinter (ADevice, ADriver, APort, ADeviceMode);
DevMode := GlobalLock(ADeviceMode);
if not Assigned(DevMode) then
ShowMessage('Ha entrado en -> if not Assigned(DevMode) ...')
else
begin
with DevMode^ do
begin
dmPaperSize:= DMPAPER_User;
dmPaperLength := intAlto;
dmPaperWidth:= intAncho;
dmFields := dmFields or DM_PAPERSIZE or DM_PAPERLength or DM_PAPERWidth;
end;
GlobalUnLock(ADeviceMode);
SetPrinter(ADevice, ADriver, APort, ADeviceMode);
end;
end;
end;


Pero harías mejor en seguir la idea de Lepe, es lo que yo utilizo en la actualidad, como ves la opción del Canvas es bastante complicada de llevar a cabo.

La función numero2Texto la cree yo.

Un Saludo.

Tauro78
29-01-2007, 17:08:51
En caso de usar QReport, me surge una pregunta, luego de definir el tamaño del papel en la impresora creo que no deberia dejar ese tamaño por defecto en la impresora, ya que solo lo usare para imprimir facturas pero todos los otros documentos se imprimen en A4, entonces como puedo hacer para que mi programa justo antes de imprimir cambie el tamaño del papel de A4 al formato definido por mi (ej: Facturas), y luego que termine de imprimir vuelva a cambiar el tamaño del papel al formato de A4 ?

marcoszorrilla
29-01-2007, 22:45:11
Lo que hago yo es instalar la misma impresora dos veces en esa segunda, que le llamo recibos, facturas o lo que sea, le pongo las medidas personalizadas que voy a utilizar que coinciden con las que he dato al tamaño personalizado de QuickReport, nunca me ha dado problemas.

Un Saludo.