Need to save additional information about reports
Hi,
I would like to save some additional information along with the reports.
Is there an analog to "OnAfterReportSave" event, where I can save something
to the database as well? Also, how do I know report id - of the just created
report? Or the id of the report that has just been modified?
Thanks,
MB
I would like to save some additional information along with the reports.
Is there an analog to "OnAfterReportSave" event, where I can save something
to the database as well? Also, how do I know report id - of the just created
report? Or the id of the report that has just been modified?
Thanks,
MB
This discussion has been closed.
Comments
rbItem dataset's field value for 'ItemID' to get the current record. For a
new report use the Report.Template.OnNew event if you want to check it in
that event.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
Thanks, the method for getting id when editing the report works just fine.
But I have some problems with getting id of the report that is just being
created.
Let's say I create a new report. How do I know an Id of the report I just
created?
If I try to get ITEM_ID on Report.Template.OnNew event it just returns me id
of the last accessed report.
Also could you please explain me what do I need to do in case when I use
OnLoadStart or OnSaveEnd events for saving custom information into file? The
problem is - I don't know how to work with streams there.
Also is there some analog to OnBeforeDelete event? Let's say I need to
delete something from database before (or after) deleting the report. Is
there a way?
Thanks,
MB
leverage the OnLoadEnd and OnSaveStart events. You don't need the stream,
just let RB handle that. I was thinking that you had extra info from your
app, in a Delphi variable or something outside of the report that you wanted
to save to the database when the report was saved. When the report is loaded
from database, I was thinking you were trying to initialize your variables
external to the report. If your data is stored in another table, then in the
Report.Template.OnSaveStart event, grab the current ItemID from the rbItem
dataset (assuming this is a foreign key in the other table to find the data
you want to change) and fire another query to update the value in the other
table.
My question is, what are your trying to save? If you need to access the
report, then there is also a template offset area you can use to store extra
info. I don't know if you were aware of this feature or not, so you don't
have to use extra fields on a database table. Here is an article explaining
this further:
-----------------------------------------------------
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}
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
Thank you for the explanation about streams and saving to the report
template.
I was aware of the template offset area but didn't quite know how to use it
(now I know though). Unfortunately I need to use both database AND template
offset area for my reoports.
About saving additional information along with the report: When(After) the
user creates a new report I must obtain Id of the report that has just been
created and fill several other tables using this id (like assigning default
rights and parameters for this report) as a reference. I can easily get this
Id if the report is being modified, but if it is created anew then I am at a
loss what to do.
Also when the report is about to be deleted I need to be able to either not
allow deleting of the report or delete some data from another tables using
Id of the report to be deleted. The problem is that I don't know where do I
have to write a handler for this(template doesn't have OnBeforeDelete event)
Could you help me with those issues, please.
extra operations based on user actions, such as detecting when deletion of a
report is occurring.
When a new report is created, a new record isn't posted. Only when the user
tries to save a report is a new record posted to the database. Use the
Report.Template.OnSaveStart event to be notified when a record is being
saved. To determine that it is new, use the OnNew event of the template or
the TppDesigner.OnCreateReport event. This way you'll know when it was
created new or if a Report.Template.OnLoadStart was called telling you that
the current report was loaded and already exists on the database.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
the Tutorials section of the RB installation.
Cheers,
Jim Bennett
Digital Metaphors
http://www.digital-metaphors.com
info@digital-metaphors.com
there is some other - easier way. Hmm.., it really seems to be the only way
to do it. Ok, thank you for the explanation, I will have to do it.