Question
“How do I store descriptive information with my report template?”
Solution
If you are storing the templates to a database, then you can use the Report.Template.OnSaveEnd and OnLoadEnd events to store and load the custom information to appropriate data fields for the record. (This is the technique used by the ReportExplorer.)
If you are storing templates to .rtm files, then you will need to store the custom information in an Offset area of the template file. The Report.Template object enables you do this by utilizing the Template.Offset property and the Template.OnLoadStart and OnLoadEnd events. Below is a detailed example.
Example:
- Create a new application.
- Add to the main form one TButton, one TppReport and one TppDesigner.
- Set the Designer’s Report property to ppReport1.
- Add ppTypes to the uses clause.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
type TForm1 = class(TForm) Button1: TButton; ppReport1: TppReport; ppDesigner1: TppDesigner; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private procedure LoadReportStreamEvent(Sender: TObject; Stream: TStream); procedure SaveReportStreamEvent(Sender: TObject; Stream: TStream); public end; { class TForm1 } {note: use compiler directive to declare strings as 'ShortStrings' this is required for record structures} {$H-} {record structure used to store information inside report template } TmyTemplateInfo = record HeaderID: Integer; Comments: String; DateTime: TDateTime; end; {record, TppTemplateRec} {$H+} const cHeaderID = 12345; implementation {-------------------------------------------------} { TForm1.FormCreate } procedure TForm1.FormCreate(Sender: TObject); begin {setup Template events } ppReport1.Template.Format := ftASCII; ppReport1.Template.Offset := SizeOf(TmyTemplateInfo); ppReport1.Template.OnLoadStart := LoadReportStreamEvent; ppReport1.Template.OnSaveEnd := SaveReportStreamEvent; end; {procedure, FormCreate} {-------------------------------------------------} { TForm1.Button1Click } procedure TForm1.Button1Click(Sender: TObject); begin ppDesigner1.Show; end; {procedure, Button1Click} {--------------------------------------------------} { TForm1.LoadReportStreamEvent } procedure TForm1.LoadReportStreamEvent(Sender: TObject; Stream: TStream); var lTemplateInfo: TmyTemplateInfo; lsMessage: String; begin {read string stored in template header } Stream.Seek(0, soFromBeginning); Stream.Read(lTemplateInfo, SizeOf(TmyTemplateInfo)); {note: if not one of the templates with our header info, then set Offset to 0 } if lTemplateInfo.HeaderID = cHeaderID then begin lsMessage := 'Reading data from template file: ' + #13#10 + #13#10 + lTemplateInfo.Comments + ' (' + DateTimeToStr(lTemplateInfo.DateTime) + ')'; MessageDlg(lsMessage, mtInformation, [mbOK],0); ppReport1.Template.Offset := SizeOf(TmyTemplateInfo); end else ppReport1.Template.Offset := 0; end; {procedure, LoadReportStreamEvent} {------------------------------------------------------------------------------} { TForm1.SaveReportStreamEvent } procedure TForm1.SaveReportStreamEvent(Sender: TObject; Stream: TStream); var lTemplateInfo: TmyTemplateInfo; lsMessage: String; begin lTemplateInfo.HeaderID := cHeaderID; lTemplateInfo.Comments := 'This comment is being stored inside the report template, ' + #13#10 + 'along with the date and time written. '; lTemplateInfo.DateTime := Now; {write info to template header} Stream.Seek(0, soFromBeginning); Stream.Write(lTemplateInfo, SizeOf(TmyTemplateInfo)); lsMessage := 'Writing data to template file: ' + #13#10 + #13#10 + lTemplateInfo.Comments + ' (' + DateTimeToStr(lTemplateInfo.DateTime) + ')'; MessageDlg(lsMessage, mtInformation, [mbOK],0); end; {procedure, SaveReportStreamEvent} |