Mega Code Archive

 
Categories / Delphi / Activex OLE
 

Master detail report using excel

Title: Master detail report using excel Question: How to make a master detail report using Excel Answer: Hi everybody! Please excuse my English. This is my first article. Let me tell you that I am not a professional programmer, in fact I didnt study to be a programmer, but I like it and I am learning by myself. I couldnt have accomplished this article with out the help from others two rticles http://www.delphi3000.com/articles/article_1814.asp from Mekan Gara and http://www.delphi3000.com/articles/article_1282.asp from Lubomir Rosenstein, but I needed an master detail report, So I took this articles and I started to find out how to do it and this is the result. If you have some comments or improvements, please let me know. 1.- Start a new project 2.- Include ComObj and Excel97 units to your uses clause 3.- Drop one Progressbar and one button on the form 4.- Drop two Ttable components and one TdataSource 5.- For this example were going to use the DBDEMOS database, so tie the first table to DBDEMOS alias using Database property, and Name it Master, and choose Customer.db in TableName property. 6.- In the second Ttable component, also tie it to DBDEMOS database, and name it Detail and choose orders.db in TableName property 7.-Tie DataSource1 to Master table in Dataset property 8.- In Detail table, tie MasterSource property to DataSource1 9.- Click on Masterfields in Detail table and choose CustNo in Available indexes combo box, then select CustNo from Detail Fields, and CustNo from Master Fields, and click Add button. And you will see in Joined Field box CustNo-CustNo click Ok button and we have our detail table ready. 10.- Set to active both Ttable components. Double click at Ttable components, and right click over the window that show up and choose Add all records, select a field, and in Object inspector change the property Visible to True or False, depending on which fields you want to appear in the report. The code: unit main; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls,ComObj, Excel97, DBTables, Db; type TForm1 = class(TForm) Button1: TButton; ProgressBar1: TProgressBar; DataSource1: TDataSource; master: TTable; Detalle: TTable; DataSource2: TDataSource; procedure ExportToExcelMasterTable,DetailTable:TDataSet;ReportTitle:String); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Implementation {$R *.DFM} { TForm1 } Const MaxCells:Array[1..25] of string[1] =('A','B','C','D','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T', 'U','V','W','X','Y','Z'); procedure TForm1.ExportToExcel(MasterTable, DetailTable: TDataSet; ReportTitle: String); var Excel:Variant; Worksheet:Variant; HeaderLine,DataLine,H,I,J,k,Done,Detail,VisibleFields:Integer; FromCell,ToCell:String; begin try Excel:=CreateOleObject(Excel.Application); ///Open excel Excel.Visible:=False; Excel.WorkBooks.Add(-4167); Excel.WorkBooks[1].Worksheets[1].Name:='Sheet1'; Worksheet:=Excel.Workbooks[1].Worksheets['Sheet1']; except MessageBox(handle,Can''t Open Excel','Error',MB_IconError); Exit; end; HeaderLine:=2; //setup initial values DataLine:=3; Done:=0; VisibleFields:=0; MasterTable.First; ProgressBar1.Max:=masterTable.RecordCount; Screen.Cursor := crHourglass; Worksheet.Range[C1,C1].Value:=ReportTitle; while not MasterTable.Eof do begin try For i:=1 to MasterTable.FieldCount do if MasterTable.Fields[i-1].Visible then begin WorkSheet.Cells[HeaderLine,i].Value:=MasterTable.Fields[i-1].DisplayName; WorkSheet.Cells[HeaderLine,i].ColumnWidth:=MasterTable.Fields[i-1].DisplayWidth; Inc(VisibleFields); end; {here we are going to give some format to headers } FromCell:=A+IntToStr(HeaderLine); {You can format the entire Row, but if you do it, when you print the document you will get a lot of empty pages} ToCell:=MaxCells[VisibleFields-1]+IntToStr(HeaderLine); VisibleFields:=0; {If your excel Its in Spanish like mine, change Bold to Negrita} WorkSheet.Range[FromCell,ToCell].Font.FontStyle:='Bold'; WorkSheet.Range[FromCell,ToCell].Interior.Color:=ClSilver; WorkSheet.Range[FromCell,ToCell].Font.Size:=09; WorkSheet.Range[FromCell,ToCell].Borders.Weight:=Xlmedium; WorkSheet.Range[FromCell,ToCell].HorizontalAlignment:=XlCenter; {Ok, let's feed master data} For h:=1 to MasterTable.FieldCount do if MasterTable.Fields[h-1].Visible then begin WorkSheet.Cells[Dataline,h].Value:=MasterTable.Fields[h-1].Text; end; Detail:=DataLine+1; DetailTable.Close; DetailTable.Open; DetailTable.First;{Put detail table at the beginning} {Headers for the detail data} For k:=1 to DetailTable.FieldCount do begin if DetailTable.Fields[k-1].Visible then begin WorkSheet.Cells[Detail,k].Value:=DetailTable.Fields[k-1].DisplayName; WorkSheet.Cells[Detail,k].Font.FontStyle:='Bold'; WorkSheet.Cells[Detail,k].HorizontalAlignment:=XlCenter; end; end; Inc(Detail); {feed detail data} While not DetailTable.Eof do Begin for j:=1 To DetailTable.FieldCount do if DetailTable.Fields[j-1].Visible=True then begin WorkSheet.Cells[Detail,J].Value:=DetailTable.Fields[j-1].Text; end; Inc(Detail); DetailTable.Next; //Process next record end; HeaderLine:=Detail+1; DataLine:=HeaderLine+1; Inc(Done); ProgressBar1.Position:=Done; MasterTable.Next; Application.ProcessMessages; {If something goes wrong} except MessageBox(handle,'Data transfer error','Error',MB_IconError); Excel.Visible:=True; Screen.Cursor := crDefault; exit; end; end; Excel.Visible:=True; Screen.Cursor := crDefault; end; {How to call it.} procedure TForm1.Button1Click(Sender: TObject); begin ExportToExcel(Master,detil,'Cool!'); end; end. Thats all folks, a hope this help you. You can download the complete project at: http://www.mexred.com/examples/mastdet.zip Enjoy.