----Delphi를 사용하여 데이터베이스를 개발한 저자의 이전 작업에서 사용자는 자신의 쿼리 결과를 기반으로 보고서를 동적으로 생성한 다음 인쇄하라는 요구 사항을 제시했습니다. 많은 탐색 끝에 저자는 사용자의 요구 사항을 충족하기 위해 QuickReport 컨트롤을 동적으로 생성하는 방법을 사용했습니다. 이 방법은 유사한 작업을 수행하는 친구들에게 유용한 팁을 제공하기 위해 아래에 설명되어 있습니다.
1. 기본 아이디어
----먼저 일부 쿼리 매개변수(예: SQL 명령, 필드 이름, 필드 너비 등)를 특정 형식의 임시 파일에 씁니다. 보고서를 생성할 때 임시 파일에 기록된 매개변수를 기반으로 다양한 QuickReport 컨트롤을 동적으로 생성하면 됩니다.
2. 프로그램 시행
2.1 임시 파일 형식
----임시 파일의 형식은 필요에 따라 사용자 정의할 수 있습니다. 작성자는 INI 파일 형식을 사용합니다. Delphi는 TInifile 클래스를 제공하므로 Delphi에서 INI 형식 파일을 조작하는 것이 매우 편리합니다. INI 파일의 형식과 특정 작업에 대한 많은 기사가 있으므로 여기서는 자세히 다루지 않겠습니다. 임시 파일 형식은 다음과 같습니다.
Report.ini
:신고 내용
[담당자_세부사항]
제목=XXXXX 테이블
: 인쇄 용지 설정, 1은 A4 용지, 2는 B5 용지, 3은 16K
페이지=1
: 인쇄 모드, 1은 가로 인쇄, 0은 세로 인쇄를 의미합니다.
방향=1
:보고서에 포함된 필드 수
열=8
:TQurey 구성요소 정보
[쿼리데이터]
: QuickReport 컴포넌트 내 Tqurey 컴포넌트의 SQL 명령어 내용
Sql_command=Hvzzjg에서 V_XM,V_JGZW,V_BMMC,V_DWMC,V_DWZW,V_ZY,V_ZC,V_BGDH를 선택합니다. 여기서 V_XM은 '이%'와 같습니다.
[col_0]
캡션=이름
데이터파일=V_XM
폭=60
…
…
2.2 QuickReport 보고서를 동적으로 생성
--- 보고서의 주요 컨트롤과 주요 속성 설정은 다음과 같습니다.
컨트롤 이름 | 수업명 | 재산 | 속성 값 |
양식_대표 | TForm | 표제 | 동적 보고서 |
QuickRep | TQuickRep | 데이터세트 | REP_QUERY |
디테일밴드1 | TQR밴드 | 밴드 유형 | rb세부사항 |
열헤더밴드1 | TQR밴드 | 밴드 유형 | rb열헤더 |
REP_데이터소스 | TDataSource | 데이터세트 | Rep_Query |
Rep_Query | TQuery | 데이터베이스 이름 | REPDATABASE |
Rep_Database | T데이터베이스 | 연결됨 | 진실 |
Params.Strings | '서버 이름=XXX '사용자 MAME=XXX' '비밀번호=XXX' | ||
데이터베이스 이름 | REPDATABASE |
위 표에 표시된 컨트롤은 프로그램에서 수동으로 생성되었습니다. 다른 컨트롤은 프로그램에서 동적으로 생성되어야 합니다.
2.2.2 주요 절차
단위 f_rep;
인터페이스
용도
Windows, 메시지, SysUtils, 변형, 클래스, 그래픽, 컨트롤, 양식,
대화 상자, ExtCtrls, QuickRpt, QRCtrls, DB, DBTables, PRINTERS, QRPrntr,inifiles,
TeeProcs, TeEngine, DbChart, QRTEE;
유형
TForm_rep = 클래스(TForm)
QuickRep: TQuickRep;
DetailBand1: TQRBand;
ColumnHeaderBand1: TQRBand;
REP_DataSource: TDataSource;
REP_QUERY: TQuery;
rep_Database: TDatabase;
절차 TForm_rep.QuickRepAfterPreview(Sender: TObject);//탐색 후 생성된 모든 컴포넌트를 해제합니다.
사적인
{비공개 선언}
공공의
{공개 선언}
끝;
var Form_rep:TForm_Rep;
type //보고서 요약 정보
C_rep_Summary=기록
Title:string;//보고서 제목
Page:TQRPaperSize;//보고서의 페이지 설정, 사용되는 용지 종류
Orientation:TPrinterOrientation;//보고서의 페이지 설정(가로 또는 세로인지 여부)
열:정수;//보고서에 포함된 열 수
끝;
유형
C_Rep_Col_Summary=record//보고서 열의 요약 정보
Caption:string;//보고서의 열 이름
DataFiled:string;//보고서 열에 해당하는 데이터베이스의 필드 이름
너비:정수;//보고서의 열 너비
끝;
유형
C_Rep_Col_Sum_store=record //보고서 열의 저장 요약 정보
Caption_array:문자열 배열;
DataFiled_array:문자열 배열;
Width_array:정수 배열;
끝;
var
대표_요약:C_rep_요약;
Rep_Col_Summary:C_Rep_Col_Summary;
Rep_Col_Sum_store:C_Rep_Col_Sum_store;
Colum_Name: tQRRichText 배열;
Colum_Data:TQRDBRichText 배열;
C_Query:TQuery;
절차 Form_rep_init();
절차 DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//TQRDBText 컨트롤을 동적으로 생성
절차 DynCreat_TQRRichtext(Colum_Num:integer);//TQRRichtext 컨트롤을 동적으로 생성
Procedure DynCreat_TQuery(Inifile_Name:Tinifile);//TQuery 컨트롤을 동적으로 생성하는 SQL 문
프로시저 Get_PageCount();//인쇄된 총 페이지 수를 가져옵니다.
function Open_IniFile():Tinifile;//임시 파일 열기
Procedure Read_Col_Summary(Inifile_Name:Tinifile);//보고서 컬럼의 요약 정보 읽기
Procedure Read_Rep_Summary(Inifile_Name:Tinifile);//보고서 요약 정보 읽기
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//인쇄 모드 설정 변환
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//인쇄 페이지 크기 설정 변환
구현
{$R *.dfm}
function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//인쇄 페이지 유형 설정 변환
시작하다
사례 Rep_Page of
1:시작
결과:=A4;
Form_rep.QuickRep.PrinterSettings.PaperSize:=A4;
끝;
2:시작
결과:=B5;
Form_rep.QuickRep.PrinterSettings.PaperSize:=B5
끝;
3:시작
결과:=임원;
Form_rep.QuickRep.PrinterSettings.PaperSize:=이그제큐티브;
끝;
끝;
끝;
function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//인쇄 모드 설정 변환
시작하다
케이스 Rep_Orientation of
0:시작
result:=poPortrait;//0은 세로입니다.
Form_rep.QuickRep.PrinterSettings.Orientation:=poPortrait;
끝;
1:시작
result:=poLandscape;//1은 수평입니다
Form_rep.QuickRep.PrinterSettings.Orientation:=poLandscape;
끝;
끝;
끝;
function Open_IniFile():Tinifile;//임시 파일 열기
var 파일명: 문자열;
Ini_파일 이름:문자열;
시작하다
파일 이름:='Report.ini';
Ini_파일 이름:=파일_경로+파일 이름;
결과:=Tinifile.Create(Ini_Filename);
끝;
Procedure Read_Rep_Summary(Inifile_Name:Tinifile);//보고서 요약 정보 읽기
var Rep_Page,Rep_Orientation:integer;
시작하다
rep_Page:=Inifile_Name.Readinteger('rep_detail','페이지',1);
Rep_Orientation:=Inifile_Name.Readinteger('rep_detail','Orientation',0);
Rep_Summary do로
시작하다
열:=Inifile_Name.Readinteger('rep_detail','columns',0);
Title:=Inifile_Name.Readstring('rep_detail','제목','이름 없는 보고서');
page:=rep_chanslatepage(Rep_Page);//인쇄 페이지 크기 변환
Orientation:=rep_chanslateOrientation(Rep_Orientation);//인쇄 모드 설정을 변환합니다.
끝;
끝;
Procedure Read_Col_Summary(Inifile_Name:Tinifile);//보고서 컬럼의 요약 정보 읽기
var i_count:정수;
시작하다
//컬럼 정보를 배열에 저장
Rep_Col_Sum_store를 사용하면
시작하다
SetLength(Caption_array,rep_Summary.Columns);
SetLength(DataFiled_array,rep_Summary.Columns);
SetLength(Width_array,rep_Summary.Columns);
끝;
i_count:=0에서 rep_Summary.Columns-1까지 수행
시작하다
Rep_Col_Summary를 사용하여 수행
시작하다
Caption:=Inifile_Name.Readstring('col_'+inttostr(i_count),'Caption','Unnamed');
DataFiled:=Inifile_Name.Readstring('col_'+inttostr(i_count),'DataFiled','');
너비:=Inifile_Name.Readinteger('col_'+inttostr(i_count),'너비',0);
끝;
Rep_Col_Sum_store를 사용하면
시작하다
Caption_array[i_count]:=Rep_Col_Summary.Caption;
DataFiled_array[i_count]:=Rep_Col_Summary.DataFiled;
너비_배열[i_count]:=Rep_Col_Summary.Width;
끝;
끝;
끝;
절차 DynCreat_TQRRichtext(Colum_Num:integer);//보고서에 있는 각 열의 중국어 이름을 표시하는 데 사용되는 TQRRichtext 컨트롤을 동적으로 생성합니다.
var Colum_Name_list:TStrings;
시작하다
Colum_Name[Colum_Num]:=tQRRichtext.Create(application) //TQRRichtext 컨트롤 생성;
열_이름[열_번호].Parent:=Form_rep.ColumnHeaderBand1;
열_이름[열_번호].Frame.DrawTop:=true;
열_이름[열_번호].Frame.DrawBottom:=true;
Form_rep.ColumnHeaderBand1.Height:=40;
열_이름[열_번호].높이:=40;
열_이름[열_번호].Font.Height:=-14;
Colum_Name[Colum_Num].Font.Name:='지옥체';
열_이름[열_번호].Top:=0;
열_이름[열_번호].Alignment:=taCenter;
열_이름[열_번호].AutoStretch:=false;
//테이블 라인 그리기
열_이름[열_번호].Frame.Style:=psSolid;
열_이름[열_번호].Frame.Width:=1;
열_이름[열_번호].Frame.DrawRight:=true;
열_이름[열_번호].Frame.DrawBottom:=true;
Colum_Num=0이면
시작하다
열_이름[열_번호].Frame.DrawLeft:=true;
끝;
//RRep_Col_Sum_store 레코드의 정보를 Colum_Name에 할당합니다.
Colum_Name_list:=TStringList.Create;
Colum_Name_list.Add(Rep_Col_Sum_store.Caption_array[Colum_Num]);
열_이름[열_번호].Lines:=열_이름_목록;
열_이름[열_번호].Width:=Rep_Col_Sum_store.Width_array[열_번호];
열_이름[열_번호].Visible:=true;
//왼쪽 경계 계산
Colum_Num>0이면
열_이름[열_번호].왼쪽:=열_이름[열_번호-1].왼쪽+열_이름[열_번호-1].너비
또 다른
열_이름[열_번호].Left:=0;
끝;
참고: 이름이 너무 길면 TQRRichtext 컨트롤이 자동으로 줄을 줄바꿈할 수 있기 때문에 여기서는 TQRRichtext 컨트롤이 사용됩니다.
절차 DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//각 열의 값을 표시하는 데 사용되는 TQRDBText 컨트롤을 동적으로 생성합니다.
시작하다
Colum_Data[Colum_Num]:=tQRDBText.Create(응용 프로그램);
Colum_Data[Colum_Num].Parent:=Form_rep.DetailBand1;
//데이터 세트 설정
컬럼_데이터[컬럼_번호].DataSet:=데이터세트_이름;
//배열 Colum_Data.DateField 속성을 C_Rep_Col_Sum_store의 필드 이름으로 설정합니다.
Colum_Data[Colum_Num].DataField:=Rep_Col_Sum_store.DataFiled_array[Colum_Num];
Colum_Data[Colum_Num].Width:=Rep_Col_Sum_store.Width_array[Colum_Num];
Colum_Data[Colum_Num].Height:=Colum_Height;
Form_rep.DetailBand1.Height:=Colum_Height;
열_데이터[열_번호].Top:=0;
Colum_Data[열_Num].AutoSize:=false;
Colum_Data[Colum_Num].AutoStretch:=false;
Colum_Data[Colum_Num].WordWrap:=false;
열_데이터[열_번호].Visible:=true;
//테이블 라인 그리기
Colum_Data[Colum_Num].Frame.Style:=psSolid;
Colum_Data[Colum_Num].Frame.DrawRight:=true;
Colum_Data[Colum_Num].Frame.DrawBottom:=true;
Colum_Num=0이면
Colum_Data[Colum_Num].Frame.DrawLeft:=true;
//왼쪽 경계 계산
Colum_Num>0이면
Colum_Data[열_Num].Left:=Colum_Data[Colum_Num-1].Left+Colum_Data[Colum_Num-1].Width
또 다른
열_데이터[열_번호].Left:=0;
끝;
Procedure DynCreat_TQuery(Inifile_Name:Tinifile);//TQuery 컨트롤의 SQL 문을 동적으로 설정합니다.
var
SQL_command:문자열;
시작하다
Flag_CreatQuery:=false;
Sql_command:=Inifile_Name.Readstring('QureyData','Sql_Command','');
Form_rep.REP_QUERY.Close;
Form_rep.REP_QUERY.SQL.Clear;
Form_rep.REP_QUERY.SQL.Append(Sql_command);
Form_rep.REP_QUERY.Prepared가 아닌 경우
Form_rep.REP_QUERY.준비;
노력하다
Form_rep.REP_QUERY.ExecSQL;
Form_rep.REP_QUERY.Active:=true;
Form_rep.REP_QUERY.AutoCalcFields:=true;
Flag_CreatQuery:=true;
제외하고
Application.MessageBox('SQL 문 오류!','시스템 프롬프트',MB_ICONWARNING);
Flag_CreatQuery:=false;
끝;
끝;
절차 Form_rep_init();
var i_count:정수;
Rep_IniFile:Tinifile;//