Subreport names
I want to save custom information about each sub report in the report
stream. This information comes from a menu I merged in and it's based
whatever report tab is selected at the time the user clicks on the menu.
Therefore, when a report is loaded and I pull this data in from the report
stream, I need to be able to match it back up with a certain subreport. But
they don't have a NAME property, so I can't use that. I can't use the index
of the report either, or it'll wack when the user deletes a preceding
subreport. What's the best way to accomplish this?
Gregg Van Oss
gregg@epicsoftware.net
stream. This information comes from a menu I merged in and it's based
whatever report tab is selected at the time the user clicks on the menu.
Therefore, when a report is loaded and I pull this data in from the report
stream, I need to be able to match it back up with a certain subreport. But
they don't have a NAME property, so I can't use that. I can't use the index
of the report either, or it'll wack when the user deletes a preceding
subreport. What's the best way to accomplish this?
Gregg Van Oss
gregg@epicsoftware.net
This discussion has been closed.
Comments
save the subreports into rtm files and use the following tech tip:
-----------------------------------------------------
Tech Tip: Storing Custom Information with Templates
-----------------------------------------------------
Question:
---------
How can I store descriptive information with my report template?
Solution:
---------
1. 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.)
2. 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.
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}
enjoy,
Ron.