[ Pobierz całość w formacie PDF ]
.Ready-to-use defaults, such as those provided by the SQLClientDataSet component,are nice, but it is important for me in real-world applications to be able to take full control andwrite the exact SQL code I want my system to execute.NOTEAnother complaint I have is that I don t really like the architecture used for the specific Client-DataSet components bound to the various technologies (BDE, ADO, dbExpress and so on).InChapter 19, COM Programming, I ll discuss an alternate approach.In particular, I dislike thefact that you cannot code for a generic base component, but have to tune your code tothe specific version of the ClientDataSet.Moreover, this architecture isn t extensible: you llhave to write a new specific component for each data access class you want to use (or towrite).This seems really contrary to the spirit of OOP and to the overall architecture of VCL.My suggestion is simply to avoid using these all-in-one components and get used to droppingthe DataSet Provider ClientDataSet triad every time you need to (or build a custom com-pound component for them).When One-Way Is Enough: Printing DataWe have seen that one of the key elements of the dbExpress library is that it returns uni-directional datasets and that we can use the ClientDataSet component (in one of its incar-nations) to store the records in a local cache.Now it is interesting to discuss at least a simpleexample where a unidirectional dataset is all we need.This is common in reporting, that is, to produce information for each record in sequencewithout needing any further access to the data.This broad category includes producingprinted reports (via a set of reporting components or using the printer directly), sending datato other applications like Microsoft Excel or Word, saving data to files (including HTMLand XML formats), and more.As I don t want to delve into HTML and XML right now, and we still haven t discussedCOM-based automation, I ll go ahead with an example of printing nothing fancy and noth-ing based on reporting components, but a simple way to produce a draft report on your videoCopyright ©2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c14.qxd 7/2/01 4:34 PM Page 639The dbExpress Library 639and printer.For this reason, I m going to use Delphi s simplest technique to produce a print-out: assigning a file to the printer with the AssignPrn RTL procedure.The example, called UniPrint, has a unidirectional SQLDataSet component, hooked to anInterBase connection and based on the following SQL statement, which joins the employeetable with the department table to display the name of the department where each employeeworks:select d.DEPARTMENT, e.FULL_NAME, e.JOB_COUNTRY, e.HIRE_DATEfrom EMPLOYEE einner join DEPARTMENT d on d.DEPT_NO = e.DEPT_NOTo handle printing, I ve written a somewhat generic routine, requiring as parameters thedata to print, a progress bar for status information, the output font, and the maximum formatsize of each field.The entire routine, listed below, uses file-print support and the graphicobjects recall technique, and formats each field in a fixed-size, left-aligned string, to producea columnar type of report.The call to the Format function has a parametric format string,built dynamically using the size of the field.Here is the code, which uses three nested try/finally blocks to release all the resourcesproperly:procedure PrintOutDataSet (data: TDataSet;progress: TProgressBar; Font: TFont; maxSize: Integer = 30);varPrintFile: TextFile;I: Integer;sizeStr: string;oldFont: TFontRecall;begin// assign the printer to a fileAssignPrn (PrintFile);Rewrite (PrintFile);// set the font and keep the original oneoldFont := TFontRecall.Create (Printer.Canvas.Font);tryPrinter.Canvas.Font := Font;trydata.Open;try// print header (field names) in boldPrinter.Canvas.Font.Style := [fsBold];for I := 0 to data.FieldCount - 1 dobeginsizeStr := IntToStr (min (data.Fields[i].DisplayWidth, maxSize));Write (PrintFile, Format ( %- + sizeStr + s ,Copyright ©2001 SYBEX, Inc., Alameda, CA www.sybex.com2874c14.qxd 7/2/01 4:34 PM Page 640640 Chapter 14 " Client/Server Programming[data.Fields[i].FieldName]));end;Writeln (PrintFile);// for each record of the datasetPrinter.Canvas.Font.Style := [];while not data.EOF dobegin// print out each field of the recordfor I := 0 to data.FieldCount - 1 dobeginsizeStr := IntToStr (min (data.Fields[i].DisplayWidth, maxSize));Write (PrintFile, Format ( %- + sizeStr + s ,[data.Fields[i].AsString]));end;Writeln (PrintFile);// advance ProgressBarprogress.Position := progress.Position + 1;data
[ Pobierz całość w formacie PDF ]