Actualmente, entre las herramientas de desarrollo de software, Delphi se ha convertido en una herramienta de desarrollo rápido reconocida mundialmente debido a sus numerosos controles, sólidas funciones de programación orientada a objetos, rápida velocidad de ejecución de código y simplicidad y facilidad de uso, combinado con un entorno de desarrollo visual y el compilador más rápido. Las herramientas de desarrollo de aplicaciones están siendo utilizadas por cada vez más programadores. Puede utilizar Delphi para escribir varias aplicaciones de Windows, especialmente el desarrollo de sistemas de gestión de información de bases de datos, lo que tiene sus ventajas únicas. En el proceso de desarrollo de un sistema de gestión de información de bases de datos, a menudo necesitamos imprimir muchos informes. Usar Delphi para diseñar informes complejos es un proceso engorroso y no es tan simple como Visual FoxPRo. Sin embargo, dado que los controles también se utilizan para diseñar informes en Delphi, podemos crear directamente los controles de informe necesarios durante la ejecución del programa para generar informes en tiempo real, y la muestra del informe generado puede ser determinada por el control del programa. Por ejemplo, cuando consultamos información de la base de datos, la estructura de la información del resultado generalmente no es fija. Si queremos imprimir los resultados de la consulta, no es suficiente diseñar un solo formato de informe. Debemos diseñar uno para toda la información de resultados posible. El formateo de informes tampoco es una buena solución. Para resolver este problema, podemos utilizar tecnología de generación de informes en tiempo real. El propósito de este artículo es presentar en detalle cómo generar informes en tiempo real a través de un ejemplo.
Este ejemplo diseñará un cuadro de diálogo de impresión, que incluye el control TQickRep y algunos controles de control de estilo de informe. La apariencia de otros formularios se muestra a continuación:
1. Descripción de la función de control
QuickRep:TQuickRep Incluye encabezado de columna (HB:TQRBand), detalles (DB:TQRBand), pie de página (FB:TQRBand), resumen (SB:TQRBand) bandas, y no incluye una TQRLabel en los detalles, pie de página o resumen. Control TQRExpr o TDBText, que se crean principalmente cuando se ejecuta el programa. La zona del encabezado de la columna incluye Título (TQRLabel) para el título del informe: TQRLabel se utiliza para condiciones de consulta. Las propiedades de título de estos dos controles se pueden cambiar arbitrariamente durante la ejecución del programa. Para evitar que se muestre QuickRep, colóquelo detrás del Panel1 (Tpanel) y expanda el Panel1 a todo el formulario;
Consulta: control de sentencia SQL TQuery, el programa generará informes basados en los resultados devueltos por la Consulta. Por lo tanto, al crear este formulario, debe especificar una declaración SQL para la propiedad Query.SQL;
En el formulario anterior, los controles incluidos en las columnas "Papel" y "Configuración de página" controlan las propiedades de QuickRep.Page. Cambiarlos cuando se ejecuta el programa cambiará directamente los valores de propiedad correspondientes del control QuickRep. se puede completar mediante el código de evento OnChange o OnExit;
El título en la columna "Configuración de contenido de impresión" es el título del informe especificado (TT:TEdit). Su valor es consistente con QuickRep.ReportTitle y Title.Caption y se puede cambiar arbitrariamente según lo especifica la casilla de verificación "Condiciones de consulta de impresión". si se imprimen las condiciones de la consulta. Si esta casilla de verificación está seleccionada controla directamente si QRSQL.Caption está vacío; la "alineación de columnas de la tabla" consta de un conjunto de botones de opción. Se utiliza principalmente para la alineación de contenido detallado al generar informes. cambiar la variable de control RD1 (Byte) valor (0 alineación automática, 1 alineación central, 2 alineación a la izquierda); "Ancho de impresión de columna de tabla" consta de un conjunto de botones de opción, que se utilizan principalmente para el ancho de los valores de columna al generar formatos de informes y su cambio. variables de control El valor de RD2 (Byte) (0 ancho automático, 1 Mismo ancho, 2 Limitar ancho máximo), al seleccionar 1 Mismo ancho, 2 Limitar ancho máximo, se le solicita ingresar el ancho en píxeles. "Método estadístico" indica si el informe incluye pie de página (FB: TQRBAND) y suma (SB); : TQRBAND ) zona.
2. Descripción del programa
El programa define los siguientes tipos:
TQRLabelName=matriz de TQRLabel;
TQRDBTextName=matriz de TQRDBText;
TQRShapeName=matriz de TQRShape;
TQRExpName=matriz de TQRExpr;
El tipo anterior es un tipo de matriz dinámica y cada elemento de los datos es una clase. Al crear controles de informes en tiempo real, la cantidad de controles que se crearán es incierta y los nombres de los controles no se pueden determinar. El uso de matrices dinámicas es una mejor solución, es decir, puede especificar arbitrariamente las dimensiones de los datos sin tener que administrar la memoria. asignación usted mismo. Este problema también facilita la liberación y el procesamiento de los controles contenidos en los informes. El programa también declara variables de los tipos anteriores de la siguiente manera:
CHBName:TQRLabelName;
NombreDB:TQRDBTextName;
CHBShape,DBShape,FBShape,SumShape:TQRShapeName;
FBName,SumName:TQRExpName;
Estas variables de matriz asignarán memoria en función de los resultados de campo devueltos por Consulta cuando se crea el formulario. Cada campo corresponde a un elemento de la matriz.
Proceso de ejecución del programa: Cuando se crea y muestra el formulario, se establece la operación de inicialización para este formulario. Muestre el valor correspondiente de la propiedad QuickRep.Page en el evento OnCreate, realice la operación Query.Open en el evento OnShow y asigne el espacio variable de la matriz de control de acuerdo con el resultado devuelto. Una vez creado el formulario, haga clic en el botón "Generar" para generar el informe (ignorando el campo de nota y el campo de fotografía) y luego haga clic en "Imprimir" y "Vista previa" para imprimir o obtener una vista previa del informe. Cuando se cambian las configuraciones después de generar el informe, se debe volver a generar el informe. Si el conjunto de resultados devuelto por la consulta tiene demasiados campos, es posible que el tamaño del papel no sea suficiente para generar todos los informes al generar el informe. Puede ajustar el tamaño del papel del informe y luego generar el informe. Cuando se cierra el formulario, se liberan los controles creados.
3. Lista de programas fuente y comentarios.
unidad PrintDlg;
interfaz
usos
Windows, Mensajes, SysUtils, Clases, Gráficos, Controles, Formularios, Cuadros de diálogo,
StdCtrls, Botones, ExtCtrls, Spin, QuickRpt,QRPrntr,impresoras, Qrctrls,
Db,DBTables,ComCtrls,SysIni;
tipo
TQRLabelName=array of TQRLabel;//Matriz dinámica de clases de control de título de columna en la franja de encabezado de columna
TQRDBTextName=matriz de TQRDBText //Matriz dinámica de controles de título de columna en la banda de detalles;
TQRShapeName=array of TQRShape; //Matriz dinámica de partes de control de línea
TQRExpName=matriz de TQRExpr; // Matriz dinámica de clase de control estadístico
TPrintForm = clase(TForm)
GroupBox1: TGroupBox;
Etiqueta5: TLabel;
BtnSet: TbitBtn;//Control del botón "Configuración"
BtnCancel: TBitBtn; // control del botón "Cerrar"
Panel1: Panel T;
BtnPrint: TBitBtn; // control del botón "Imprimir"
BtnPrview: TBitBtn; // botón "Vista previa"
QuickRep: TQuickRep; // Control de informe rápido
HB: TQRBand; // control de banda "encabezado de columna"
Título: TQRLabel;//Control de título del informe
QRE1: TQRExpr;//Control "Número de página" en la banda del encabezado de la columna
QRE2: TQRExpr;//Control "Fecha" en la banda del encabezado de la columna
Panel2: Panel T;
Etiqueta1: TLabel;
R1: TRadioButton;//control "Impresión vertical"
R2: TRadioButton;//control de "impresión horizontal"
GroupBox4: TGroupBox;
TT: TEdit;//Control del cuadro de entrada de título
Etiqueta2: TLabel;
SR: TCheckBox; // control "Imprimir condiciones de consulta"
Etiqueta3: TLabel;
Imagen1: TImage;//Mostrar imagen de impresión vertical
Imagen2: TImage;//Mostrar imagen de impresión horizontal
QRSQL: TQRLabel // Se utiliza para mostrar el control "Condición de consulta" en la banda del encabezado de la columna.
GroupBox2: TGroupBox;
Etiqueta7: TLabel;
Etiqueta8: TLabel;
Etiqueta9: TLabel;
Etiqueta10: TLabel;
Etiqueta11: TLabel;
Etiqueta12: TLabel;
Etiqueta13: TLabel;
PageSpace: TEdit; // control del cuadro de entrada de espaciado de columnas
PageTop: TEdit; // Control del cuadro de entrada en el margen de la página
PageBottom: TEdit; //Control del cuadro de entrada debajo del margen de la página
PageLeft: TEdit; // control del cuadro de entrada del margen izquierdo de la página
PageRight: TEdit; // control del cuadro de entrada del margen derecho de la página
PageDlux: TCheckBox; // control "Impresión a doble cara"
PageCol: TEdit; // control del cuadro de entrada de columna
Páginas: TEdit; // Imprimir control del cuadro de entrada del número
PaperH: TEdit; // control del cuadro de entrada de longitud del papel
PaperW: TEdit;//Control del cuadro de entrada del ancho del papel
Etiqueta4: TLabel;
Etiqueta6: TLabel;
Ps: TComboBox; // Control del cuadro de lista del modelo de papel
Consulta: TQuery;//control de consulta SQL
DB: TQRBand; // control de banda "Detalles"
CrtRep: TBitBtn; // control del botón "Generar"
Etiqueta14: TLabel;
Etiqueta15: TLabel;
Panel3: Panel T;
Wdauto: TRadioButton; // control "ancho automático"
Wdall: TRadioButton; // control "Mismo ancho"
Wdmax: TRadioButton; // control "Limitar al ancho"
Etiqueta16: TLabel;
ColWd: TEdit; // control del cuadro de entrada del ancho de columna
Panel4: Panel T;
DJAUTO: TRadioButton; // control de "alineación automática"
DJCENTER: TRadioButton; // control "Centro"
DJLEFT: TRadioButton; // control "Alinear a la izquierda"
FB: TQRBand // Control de banda de pie de página
Etiqueta17: TLabel;
Panel5: Panel T;
TJ1: TCheckBox; // control "Estadísticas por página"
TJ2: TCheckBox; // control "Suma estadística"
SB: TQRBand; // Control de banda de suma
procedimiento FormCreate(Remitente: TObject);
procedimiento RadioButtonClick (Remitente: TObject);
procedimiento PageDluxClick(Remitente: TObject);
procedimiento PageColChange(Remitente: TObject);
procedimiento PageSpaceExit(Remitente: TObject);
procedimiento PagesChange(Remitente: TObject);
procedimiento PageTopExit(Remitente: TObject);
procedimiento PageBottomSalir(Remitente: TObject);
procedimiento PageLeftExit(Remitente: TObject);
procedimiento PageRightExit(Remitente: TObject);
procedimiento TTExit(Remitente: TObject);
procedimiento DTClick(Remitente: TObject);
procedimiento BtnPrviewClick(Remitente: TObject);
procedimiento BtnSetClick(Remitente: TObject);
procedimiento PsChange(Remitente: TObject);
procedimiento PaperChange(Remitente: TObject);
procedimiento FormClose(Remitente: TObject; var Acción: TCloseAction);
procedimiento FormDestroy(Remitente: TObject);
procedimiento CreateReport(Remitente: TObject);
procedimiento SRClick(Remitente: TObject);
procedimiento ClearRep();
procedimiento FormShow(Remitente: TObject);
procedimiento PaperSizeChg(Remitente: TObject);
procedimiento DJChage(Remitente: TObject);
procedimiento WdChage(Remitente: TObject);
procedimiento QuickRepStartPage (Remitente: TCustomQuickRep);
procedimiento BtnPrintClick(Remitente: TObject);
privado
{Declaraciones privadas}
CHBName:TQRLabelName;//Definir nombre de control de tira de encabezado de columna nombre de matriz dinámica
DBName:TQRDBTextName //Definir el nombre de la matriz dinámica del nombre del control de banda detallada
CHBShape,DBShape,FBShape,SumShape:TQRShapeName //Definir el nombre de la matriz dinámica del control de línea;
FBName,SumName:TQRExpName //Defina el nombre de la matriz dinámica de los nombres de control de pie de página (FBNAME) y banda de suma (SUMNAME);
DJ:TAlignment;//Alineación de columnas (taLeftJustify, taRightJustify, taCenter)
Rd1, Rd2:Byte; //Se utiliza para guardar los nombres de las variables de estado de alineación de columnas de la tabla (RD1) y ancho de impresión (RD2).
público
{Declaraciones públicas}
CXTJ,BT:String;//CXTJ almacena condiciones de consulta, BT almacena títulos de informes
//Especificado por el formulario de nivel superior
fin;
constante
Tamaño del papel:matriz[0..26] de TQRPaperSize=(A3, A4, A4Small, A5, B4, B5, Letter,
Carta pequeña, Tabloide, Libro mayor, Legal, Declaración, Ejecutivo, Folio,
Cuarto, qr10X14, qr11X17, Nota, Env9, Env10, Env11, Env12,
Env14, CSheet, DSheet, ESheet, Personalizado);
//Tipos de papel listados por QuickRep
var
Imprimir formulario: TPrintForm;
implementación
{$R *.DFM}
procedimiento TPrintForm.FormCreate(Remitente: TObject);
//Mostrar la propiedad QuickRep.Page y otros valores de propiedad
var
I:Byte;
comenzar
PageCol.Text:=IntToStr(QuickRep.Page.Columns);
PageSpace.Text:=FormatFloat('0.00',QuickRep.Page.ColumnSpace);
PageTop.Text:=FormatFloat('0.00',QuickRep.Page.TopMargin);
PageBottom.Text:=FormatFloat('0.00',QuickRep.Page.BottomMargin);
PageLeft.Text:=FormatFloat('0.00',QuickRep.Page.LeftMargin);
PageRight.Text:=FormatFloat('0.00',QuickRep.Page.RightMargin);
PageSpace.Text:=FormatFloat('0.00',QuickRep.page.ColumnSpace);
R1.Checked:=QuickRep.Page.Orientation=poPortrait;
Imagen1.Visible:=R1.Comprobado;
R2.Checked:=QuickRep.Page.Orientation=poLandscape;
Imagen2.Visible:=R2.Comprobado;
PageDlux.Checked:=QuickRep.PrinterSettings.Duplex;
Pages.Text:=IntToStr(QuickRep.PrinterSettings.Copies);
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
Para I:=0 a 26 hacer //El cuadro de lista PS muestra el tipo de papel
si QuickRep.Page.PaperSize=PaperSize[I] entonces comience
PS.ItemIndex:=I;
Romper;
fin;
//Determine si el ancho del papel se puede cambiar. Solo se puede cambiar si el tipo de papel está personalizado (Ps.ItemIndex=26).
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
fin;
procedimiento TPrintForm.RadioButtonClick(Remitente: TObject);
// Manejo de eventos de cambio de orientación del papel
var
S: Cadena;
comenzar
Imagen1.Visible:=R1.Comprobado;
Imagen2.Visible:=R2.Comprobado;
si R1.Marcado entonces
QuickRep.Page.Orientation:=poRetrato
demás
QuickRep.Page.Orientation:=poLandscape;
//Intercambia los valores de ancho y largo del papel.
S:=PapelH.Texto;
PapelH.Texto:=PapelW.Texto;
PapelW.Text:=S;
si (Ps.ItemIndex=26) o (Ps.ItemIndex=0) entonces comience
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
fin;
fin;
procedimiento TPrintForm.PageDluxClick(Remitente: TObject);
comenzar
QuickRep.PrinterSettings.Duplex:=PageDlux.Checked;
fin;
procedimiento TPrintForm.PageColChange(Remitente: TObject);
comenzar
si StrToInt(PageCol.Text)<1 entonces PageCol.Text:='1';
QuickRep.Page.Columns:=StrToInt(PageCol.Text);
fin;
procedimiento TPrintForm.PageSpaceExit(Remitente: TObject);
comenzar
QuickRep.Page.ColumnSpace:=StrToFloat(PageSpace.Text);
fin;
procedimiento TPrintForm.PagesChange(Remitente: TObject);
comenzar
si StrToInt(Pages.Text)<1 entonces Pages.Text:='1';
QuickRep.PrinterSettings.Copies:=StrToInt(Pages.Text);
fin;
procedimiento TPrintForm.PageTopExit(Remitente: TObject);
comenzar
QuickRep.Page.TopMargin:=StrToFloat(PageTop.Text);
fin;
procedimiento TPrintForm.PageBottomExit(Remitente: TObject);
comenzar
QuickRep.Page.BottomMargin:=StrToFloat(PageBottom.Text);
fin;
procedimiento TPrintForm.PageLeftExit(Remitente: TObject);
comenzar
QuickRep.Page.LeftMargin:=StrToFloat(PageLeft.Text);
fin;
procedimiento TPrintForm.PageRightExit(Remitente: TObject);
comenzar
QuickRep.Page.RightMargin:=StrToFloat(PageRight.Text);
fin;
procedimiento TPrintForm.TTExit(Sender: TObject);//Manejo de eventos de cambio de título
comenzar
QuickRep.ReportTitle:=TT.Texto;
Título.Caption:=TT.Texto;
Bt:=TT.Texto;
fin;
procedimiento TPrintForm.DTClick(Sender: TObject);//Evento de casilla de verificación de condición de consulta de impresión
comenzar
QRSQL.Enabled:=SR.Comprobado;
fin;
procedimiento TPrintForm.BtnPrviewClick(Sender: TObject //Evento de clic del botón de vista previa);
comenzar
Vista previa de QuickRep;
fin;
procedimiento TPrintForm.BtnSetClick(Sender: TObject //Establecer evento de clic del botón);
comenzar
QuickRep.ImpresoraConfiguración;
fin;
procedimiento TPrintForm.PsChange(Sender: TObject);//Evento de cambio de tipo de papel
comenzar
QuickREp.Page.PaperSize:=PaperSize[Ps.ItemIndex];
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
CrtRep.Enabled:=Verdadero;
BtnPrint.Enabled:=no CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
fin;
procedimiento TPrintForm.PaperChange(Sender: TObject);//Eventos de cambio de ancho y largo del papel
comenzar
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
fin;
procedimiento TPrintForm.FormClose(Remitente: TObject; var Acción: TCloseAction);
comenzar
Acción:=caFree;
fin;
procedimiento TPrintForm.FormDestroy(Remitente: TObject);
comenzar
ClearRep;
Imprimir formulario:=nulo;
fin;
procedimiento TPrintForm.CreateReport(Sender: TObject);//Generar evento de clic en el botón
var
I,L:Byte;
CHBtp,CHBlf,Cd,ObAncho:Palabra;
comenzar
Pantalla.Cursor:=crHourGlass;
Title.Caption:=Bt;//Establecer el título
ClearRep(); //Borrar el objeto creado;
si Sr.Checked entonces QrSQL.Caption:=CXTJ else QRSQL.Caption:=';// ¿Si se imprimen las condiciones de la consulta?
CHBtp:=HB.Height-17;//La posición superior del control creado en la banda
CHBlf:=0; //El control creado está en la posición izquierda de la banda
ObWidth:=0; //El ancho del control creado
para I: = 0 a Query.FieldCount-1 hacer //Crear un control basado en la cantidad de campos devueltos por Query
comenzar
si (Query.Fields[I].DataType<>ftBlob) y (Query.Fields[I].DataType<>ftMemo) entonces
comenzar //Ignorar el campo de nota y el campo de foto
L:=Query.Fields[I].DataSize-1;//L=ancho de campo (bytes)-1
case Rd1 of //Establece la alineación del control de acuerdo con la alineación seleccionada
0: si L<=10 entonces Dj:=taCenter else DJ:=taLeftJustify;
//Alineación automática: los campos menores o iguales a 10 se alinean en el centro; de lo contrario, se alinean a la izquierda
1: Dj:=taCenter;//alineación central
2: DJ:=taLeftJustify;//Alineación a la izquierda
fin;
case Rd2 of //Establece el ancho de la columna del informe de acuerdo con el ancho de la lista seleccionada
0: comenzar
//Ancho automático: si L>14 entonces ancho ObWidth=14+(L-14)/2 if ObWidth;
//El ancho no puede mostrar los títulos de las columnas, entonces ObWidth=ancho del título de la columna si el tipo de campo;
//Para tipo de fecha, tipo de moneda y tipo de número de punto flotante, ObWidth=65
si L>14 entonces L:=14+(L-14) div 2;
Ancho Ob:=L*6;
L:=Longitud(Query.Fields[I].DisplayName);
si ObWidth<L*6 entonces ObWidth:=L*6;
AnchoOb:=AnchoOb+2;
si (Query.Fields[I].DataType=ftDateTime) o
(Query.Fields[I].DataType=ftFloat) o
(Query.Fields[I].DataType=ftCurrency) luego ObWidth:=65;
fin;
1: si ColWd.Text<>' entonces ObWidth:=StrToInt(ColWd.Text)
else ObWidth:=100;//Mismo ancho:ObWidth=valor de ancho de entrada
2: comenzar // Limitar el ancho máximo: primero calcule el ancho automático y luego determine si el ancho excede el valor máximo.
//Si excede ObWidth=valor de entrada de ancho máximo
si ColWd.Text<>' entonces Cd:=StrToInt(ColWd.Text)
de lo contrario Cd:=200;
Ancho Ob:=L*6;
si ObWidth>Cd entonces ObWidth:=Cd;
AnchoOb:=AnchoOb+2;
si (Query.Fields[I].DataType=ftDateTime) o
(Query.Fields[I].DataType=ftFloat) o
(Query.Fields[I].DataType=ftCurrency) luego ObWidth:=65;
fin;
fin;
si CHBlf+ObWidth>=HB.Width entonces comenzar //Crear control>ancho del papel?
DlgMes:='El ancho del papel no es suficiente, cambie el tamaño del papel. ';
Cuadro de mensaje(Handle,DlgMes,Cap_Inf,Ico_Inf);
romper;
fin
si no, empezar
CHBShape[I]:=TQRShape.Create(HB);//Crear control de línea de franja de encabezado de columna
CHBShape[I].Padre:=HB;
FormaCHB[I].Arriba:=CHBtp;
FormaCHB[I].Izquierda:=CHBlf;
CHBShape[I].Ancho:=ObAncho+1;
CHBForma[I].Altura:=17;
CHBNAME[I]:=TQRLabel.Create(HB); //Crear control de título de columna
CHBNAME[I].Padre:=HB;
NOMBRECHB[I].Arriba:=CHBtp+2;
CHBNAME[I].Izquierda:=CHBlf+1;
CHBNAME[I].AutoSize:=Falso;
CHBNAME[I].Ancho:=ObWidth-1;
CHBNAME[I].Alineación:=taCenter;
CHBNAME[I].Caption:=Query.Fields[I].DisplayName;//Obtener el campo como nombre de la columna
CHBNAME[I].BringToFront;
DBShape[I]:=TQRShape.Create(DB); //Crear control de línea de franja detallada
DBShape[I].Padre:=DB;
FormaDB[I].Arriba:=-1;
DBShape[I].Izquierda:=CHBlf;
DBShape[I].Ancho:=ObAncho+1;
FormaDB[I].Altura:=17;
DBNAME[I]:=TQRDBText.Create(DB); //Crear control de banda detallada
NOMBREBD[I].Padre:=DB;
NOMBREBD[I].ParentReport:=QuickRep;
NOMBREBD[I].Arriba:=2;
NOMBREBD[I].Izquierda:=CHBlf+2;
NOMBREBD[I].AutoSize:=False;
DBNAME[I].Ancho:=ObWidth-3;
NOMBREBD[I].Altura:=13;
NOMBREBD[I].Alineación:=Dj;
DBNAME[I].DataSet:=Consulta;
DBNAME[I].DataField:=Query.Fields[I].FieldName;
NOMBREBD[I].BringToFront;
si Tj1.Checked entonces comienza // ¿Quieres crear una banda de pie de página?
FBShape[I]:=TQRShape.Create(FB); //Crear control de línea de banda de pie de página
FBShape[I].Padre:=FB;
FBShape[I].Arriba:=0;
FBShape[I].Izquierda:=CHBlf;
FBShape[I].Ancho:=ObAncho+1;
FormaFB[I].Altura:=17;
si (Query.Fields[I].DataType=ftFloat) o
(Query.Fields[I].DataType=ftCurrency) o (I<2) entonces
comenzar //Si el tipo de campo es de tipo numérico, créelo
FBNAME[I]:=TQRExpr.Create(FB); //Crear control de banda de pie de página
FBNAME[I].Padre:=FB;
FBNAME[I].ParentReport:=QuickRep;
FBNAME[I].Arriba:=3;
FBNAME[I].Izquierda:=CHBlf+2;
FBNAME[I].AutoSize:=Falso;
FBNAME[I].Ancho:=ObWidth-3;
FBNAME[I].Altura:=13;
FBNAME[I].Alineación:=taCenter;
FBNAME[I].Expresión:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
FBNAME[I].BringToFront;
fin;
fin;
si Tj2.Checked entonces comienza // ¿Deberíamos establecer la banda de suma?
SumShape[I]:=TQRShape.Create(SB); //Crea un control de línea de franja de suma
FormaSuma[I].Padre:=SB;
FormaSuma[I].Arriba:=0;
FormaSuma[I].Izquierda:=CHBlf;
FormaSuma[I].Ancho:=AnchoOb+1;
FormaSuma[I].Altura:=17;
si (Query.Fields[I].DataType=ftFloat) o
(Query.Fields[I].DataType=ftCurrency) o (I<2) entonces
comenzar //Si el tipo de campo es de tipo numérico, créelo
SumNAME[I]:=TQRExpr.Create(SB); //Crear control de banda de suma
SumaNOMBRE[I].Padre:=SB;
SumNAME[I].ParentReport:=QuickRep;
SumaNOMBRE[I].Arriba:=3;
SumaNOMBRE[I].Izquierda:=CHBlf+2;
SumNAME[I].AutoSize:=False;
SumaNOMBRE[I].Ancho:=ObAncho-3;
SumaNOMBRE[I].Altura:=13;
SumaNOMBRE[I].Alineación:=taCenter;
SumNAME[I].Expresión:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
SumaNOMBRE[I].TraerAlFront;
fin;
fin;
CHBlf:=CHBlf+ObWidth;//El procesamiento del campo actual se completa, un ancho de campo a la derecha
fin;
fin;
fin;
CrtRep.Enabled:=False;//Deshabilitar el botón de generación
BtnPrint.Enabled:=not CrtRep.Enabled;Permitir impresión de botones de amonio
BtnPrview.Enabled:=BtnPrint.Enabled;Permitir botón de vista previa
si Tj1.Checked entonces comenzar //Si se crea una banda de pie de página, cambie las dos primeras columnas de la banda de pie de página
FBNAME[0].Expression:=''Total de páginas'';
FBNAME[1].Expresión:='COUNT+'fila'';
fin;
si Tj1.Checked entonces comience //Si se establece la banda de suma, cambie las dos primeras columnas de la banda de suma
SumaNOMBRE[0].Expresión:=''Total'';
SumaNOMBRE[1].Expresión:='CONTAR+'fila'';
fin;
//Ajusta la posición de impresión de la fecha y el número de página en la zona del encabezado de la columna
QRE2.Izquierda:=HB.Ancho-Qre2.Ancho;
QRSQL.Izquierda:=QRE1.Ancho+10;
QRSQL.Ancho:= QRE2.Left-10-QRSQL.Left;
QuickRep.DataSet:=Query; //Especifique el conjunto de datos para QuickRep, esta oración no debe faltar
Pantalla.Cursor:=crDefault;
fin;
procedimiento TPrintForm.ClearRep();//Borrar el control creado al generar el formato del informe
var
I:Byte;
comenzar
Para I:=0 a Query.FieldCount-1 comience
si está asignado (CHBShape[I]), comience CHBShape[I].Free;CHBShape[I]:=nil;end;
si está asignado (CHBNAME[I]), comience CHBNAME[I].Free;CHBNAME[I]:=nil;end;
si está asignado (DBShape[I]), comience DBShape[I].Free;DBShape[I]:=nil;end;
si está asignado (DBNAME[I]), comience DBNAME[I].Free;DBNAME[I]:=nil;end;
si está asignado (FBShape[I]), comience FBShape[I].Free;FBShape[I]:=nil;end;
si está asignado (FBNAME[I]), comience FBNAME[I].Free;FBNAME[I]:=nil;end;
si está asignado (SumShape[I]), comience SumShape[I].Free;SumShape[I]:=nil;end;
si está asignado (SumNAME[I]), comience SumNAME[I].Free;SumNAME[I]:=nil;end;
fin;
fin;
procedimiento TPrintForm.SRClick(Remitente: TObject);
comenzar
si Sr.Checked entonces QrSQL.Caption:=CXTJ else QRSQL.Caption:=';
fin;
procedimiento TPrintForm.FormShow(Sender: TObject //Evento de visualización del formulario);
comenzar
Query.Active:=True;//Imprimir SQL
TT.Texto:=Bt;
QuickRep.ReportTitle:=Bt;//Establecer el título
//La matriz de nombres de control asigna espacio
EstablecerLongitud(CHBNAME,Query.FieldCount);
EstablecerLongitud(CHBShape,Query.FieldCount);
SetLength(DBNAME,Query.FieldCount);
SetLength(DBShape,Query.FieldCount);
EstablecerLongitud(FBNAME,Query.FieldCount);
EstablecerLongitud(FBShape,Query.FieldCount);
SetLength(SumNAME,Query.FieldCount);
SetLength(SumShape,Query.FieldCount);
fin;
procedimiento TPrintForm.PaperSizeChg(Remitente: TObject);
comenzar
CrtRep.Enabled:=Verdadero;
BtnPrint.Enabled:=no CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
fin;
procedimiento TPrintForm.DJChage(Sender: TObject);//Manejo de eventos de cambio de alineación
var
Cambio:Byte;
comenzar
si Djauto.Checked entonces Chg:=0
de lo contrario, si DjCenter.Checked entonces Chg:=1
de lo contrario Cambio:=2;
si Chg<>Rd1 entonces comienza PaperSizeChg(nil);Rd1:=Chg;end;
fin;
procedimiento TPrintForm.WdChage(Sender: TObject);//Manejo de eventos de cambio de ancho
var
Cambio:Byte;
comenzar
si Wdauto.Checked entonces Chg:=0
de lo contrario, si Wdall.Checked entonces comienza
Cambio:=1;
si ColWd.Text=' entonces ColWd.Text:='100';
fin
si no, empezar
Cambio:=2;
si ColWd.Text=' entonces ColWd.Text:='200';
fin;
si Chg<>Rd2 entonces comienza PaperSizeChg(nil);Rd2:=Chg;end;
ColWd.Enabled:=Camb<>0;
fin;
procedimiento TPrintForm.QuickRepStartPage(Remitente: TCustomQuickRep);
// La impresión del informe inicia el procesamiento de eventos de nueva página y se borran los valores estadísticos en la banda del pie de página.
var
I:Byte;
comenzar
si Tj1.Comprobado entonces
Para I:=0 a Query.FieldCount-1 haga
si está asignado (FBNAME[I]) entonces FBNAME[I].Reset;
fin;
procedimiento TPrintForm.BtnPrintClick(Remitente: TObject);
comenzar
Impresión.Rep.Rápida;
fin;
fin.
4. Ejemplo de cuadro de diálogo de llamada:
Primero, incluya la unidad PrintDlg en la declaración USES en el formulario que se llamará y luego llámela con el siguiente código:
si no está asignado (PrintForm), entonces PrintForm:=TPrintForm.Create(application);
PrintForm.Query.SQL.Assign(Query.SQL);
// Si el formulario de llamada no contiene un control de consulta, puede establecer directamente el valor de la declaración SQL
PrintForm.Bt:=Título del informe;
PrintForm.Caption:=Título del formulario;
PrintForm.CXTJ:=condiciones de consulta;
ImprimirForm.ShowModal;
5. Conclusión
La clave de este programa es el proceso de eventos CreateReport y el procesamiento de nombres de controles dinámicos. Debido al espacio limitado, algunos contenidos no se explican y espero que los lectores puedan entenderlos por sí mismos. Para la generación de informes generales, este programa puede cumplir con los requisitos.
Tengo la última versión, que tiene funciones más potentes. Los amigos que la necesiten pueden enviarme un correo electrónico y definitivamente se lo enviaré.