is there a way to let the user edit the report in the previewform? It would be great, to have the possibility to add some text to the report or to change text.
Although it is not recommended, it may be possible to use the DrawCommandClick event of a report component to allow your users to click on a text value, then have a dialog pop up and allow them to change the text. Then you would need to call Report.Reset to refresh the preview window. Be sure you do not make any datasource or data access changes as this will probably confuse the report engine and alter the output of the report.
The DrawCommandClick is a published event of every report component. Simply place an object on a report, click the Events tab of the object inspector and double click the OnDrawCommandClick event to access the event. From here you can add any code you like to execute when the object is clicked in the previewer.
o.k. I understand, but I fear I cannot do that, because I do not create reports at designtime. I let the enduser create reports at runtime. Is there any way, to give all used report components a default ondrawcommandclick event, so that the event is fired for every component placed on the report at runtime?
I think I found a solution for my problem. I just iterate all bands of the report and all objects of the bands, before I show the previewform. Then I check if the component should be able to be edited and set the ondrawcommandclick event of this component to an eventhandler, which allows me to control the edititing of the text.
Thanks for the great tip with this event. I think I will be able to solve it now.
1st: Iterating through bands and objects of the bands doesn't bring me all components. Could you tell me a way to iterate all printable components of a report. Especially I need a method to iterate all objects depemding on datafields.
2nd: report.reset doesn't refresh the prieviewform. To preview I need a Form, where I placed a tppviewer and a tppreport. I need a method to refresh the viewer after changing the text of a tppcomponent.
begin s := tppcomponent (sender).text; memodialog (s); if s <> tppcomponent (sender).text then begin tppcomponent (sender).text := s; report.reset; end; end;
This doesn't work. The Previewwindow is not refreshed.
thanks for your hints, but I fear they don't work as I need it.
1. For looping through all objects, I do it as you describe it and it works fine in a simple report, but it doesn't work in a report with subreports. I cannot get the objects of the subreports.
2. TppViewer.RegenerateReport doesn't refresh the report so that the changes to an object are displayed. I discovered, that calling
viewer.zoomsetting := viewer.zoomsetting;
does so, but after changing the page or printing to the printer, it is set back to the value after generating the report.
cu Helmut P.S. sorry for the answer per email. I just pressed the wrong button;-)
It is possible to loop through all components including the subreports by creating a recursive method that calls itself when it hits a subreport component.
thanks for this hint. Now I successfully could loop through all components and set the ondrawcommandclick event of all objects of the type tppcustomtext and TppCustomMemo. It works very well.
In the ondrawcommandclick event I do the following:
begin if tppdrawtext (adrawcommand).ismemo then s := trim (tppdrawtext (adrawcommand).wrappedtext.text) else s := trim (tppdrawtext (adrawcommand).text); memodialog (s); if tppdrawtext (adrawcommand).ismemo and (trim (s) <> tppdrawtext (adrawcommand).wrappedtext.text) or not tppdrawtext (adrawcommand).ismemo and (trim (s) <> tppdrawtext (adrawcommand).text) then begin if tppdrawtext (adrawcommand).ismemo then tppdrawtext (adrawcommand).wrappedtext.text := trim (s) else tppdrawtext (adrawcommand).text := trim (s); viewer.zoomsetting := viewer.zoomsetting; end; end;
After that the changed text appears in the preview.
The problem is, that the report is regenerated when it is printing or when I change to another page in the previewwindow, so that the changes made are cancelled.
How could I prevent the report to be regenerated after I changed the text of the tppdrawcommands?
How could I save the previewed and changed report, so that I cann reload it later, without generating it again, so that the changes made, are permanent, until the user explicit generates the report new?
Helmut
"Am Tue, 24 Feb 2004 08:09:06 -0700, schrieb "Nico Cizik \(Digital
First, I must emphasize that this type of application is not what ReportBuilder was designed to do. From experience, the more you ask of ReportBuilder during or after report generation, the harder it gets to obtain the results you want.
Keeping that in mind...
1. The reason setting zoomsetting := zoomsetting redraws the page is that when you set the zoomsetting, the screen device renders the page again and the page is refreshed. You can accomplish the same thing with essentially less code by calling
2. Simply changing the properties of the drawcommands will not affect the actual report components, so when the report is printed or saved, you will not see the changes. A workaround for this would be to change the actual component properties by accessing the TppDrawCommand.Component property. Below is some code I wrote to do just that. Hope this helps.
procedure TForm1.ppLabel1DrawCommandClick(Sender, aDrawCommand: TObject); begin TppDrawText(aDrawCommand).Text := 'Nico can''t code';
Comments
Although it is not recommended, it may be possible to use the
DrawCommandClick event of a report component to allow your users to click on
a text value, then have a dialog pop up and allow them to change the text.
Then you would need to call Report.Reset to refresh the preview window. Be
sure you do not make any datasource or data access changes as this will
probably confuse the report engine and alter the output of the report.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
could you explain to me where I can find the drawcommandclick event
and get access to it?
Is there any example for doing that?
Helmut
The DrawCommandClick is a published event of every report component. Simply
place an object on a report, click the Events tab of the object inspector
and double click the OnDrawCommandClick event to access the event. From
here you can add any code you like to execute when the object is clicked in
the previewer.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
o.k. I understand, but I fear I cannot do that, because I do not
create reports at designtime. I let the enduser create reports at
runtime. Is there any way, to give all used report components a
default ondrawcommandclick event, so that the event is fired for every
component placed on the report at runtime?
Helmut
I think I found a solution for my problem. I just iterate all bands of
the report and all objects of the bands, before I show the
previewform. Then I check if the component should be able to be edited
and set the ondrawcommandclick event of this component to an
eventhandler, which allows me to control the edititing of the text.
Thanks for the great tip with this event. I think I will be able to
solve it now.
Helmut
I thought I got it, but I didn't;-(
2 Problems:
1st: Iterating through bands and objects of the bands doesn't bring me
all components.
Could you tell me a way to iterate all printable components of a
report. Especially I need a method to iterate all objects depemding on
datafields.
2nd: report.reset doesn't refresh the prieviewform.
To preview I need a Form, where I placed a tppviewer and a tppreport.
I need a method to refresh the viewer after changing the text of a
tppcomponent.
I tried the following:
procedure Tfrmpreview.drawcommandclick(Sender, aDrawCommand: TObject);
var
s : string;
begin
s := tppcomponent (sender).text;
memodialog (s);
if s <> tppcomponent (sender).text then
begin
tppcomponent (sender).text := s;
report.reset;
end;
end;
This doesn't work. The Previewwindow is not refreshed.
Could you please help me with a little hint?
Helmut
1. Check out the article below for an example of looping through all
objects in a report.
2. Try calling TppViewer.RegenerateReport.
----------------------------------------------
Tech Tip: Loop Thru All Objects in a Report
---------------------------------------------
A ReportBuilder report is composed of a set
of components. The basic structure is
Reports.Bands[].Objects[]
The bands and objects within the report can
be accessed directly by object name or
via the Bands and Objects array properties.
Below is an example of using the Bands and
Objects array properties to change the font for
all objects on a report.
uses
ppClass;
procedure AssignFontToReport(aFont: TFont; aReport: TppCustomReport);
var
liBand: Integer;
liObject: Integer;
lObject: TppComponent;
begin
for liBand := 0 to aReport.BandCount-1 do
for liObject := 0 to aReport.Bands[liBand].ObjectCount-1 do
begin
lObject := aReport.Bands[liBand].Objects[liObject];
if lObject.HasFont then
lObject.Font := aFont;
end;
end;
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
thanks for your hints, but I fear they don't work as I need it.
1. For looping through all objects, I do it as you describe it and it
works fine in a simple report, but it doesn't work in a report with
subreports. I cannot get the objects of the subreports.
2. TppViewer.RegenerateReport doesn't refresh the report so that the
changes to an object are displayed.
I discovered, that calling
viewer.zoomsetting := viewer.zoomsetting;
does so, but after changing the page or printing to the printer, it is
set back to the value after generating the report.
cu
Helmut
P.S. sorry for the answer per email. I just pressed the wrong
button;-)
It is possible to loop through all components including the subreports by
creating a recursive method that calls itself when it hits a subreport
component.
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
thanks for this hint. Now I successfully could loop through all
components and set the ondrawcommandclick event of all objects of the
type tppcustomtext and TppCustomMemo.
It works very well.
In the ondrawcommandclick event I do the following:
procedure Tfrmpreview.drawcommandclick(Sender, aDrawCommand: TObject);
var
s : string;
begin
if tppdrawtext (adrawcommand).ismemo then
s := trim (tppdrawtext (adrawcommand).wrappedtext.text)
else
s := trim (tppdrawtext (adrawcommand).text);
memodialog (s);
if tppdrawtext (adrawcommand).ismemo and (trim (s) <> tppdrawtext
(adrawcommand).wrappedtext.text) or
not tppdrawtext (adrawcommand).ismemo and (trim (s) <> tppdrawtext
(adrawcommand).text) then
begin
if tppdrawtext (adrawcommand).ismemo then
tppdrawtext (adrawcommand).wrappedtext.text := trim (s)
else
tppdrawtext (adrawcommand).text := trim (s);
viewer.zoomsetting := viewer.zoomsetting;
end;
end;
After that the changed text appears in the preview.
The problem is, that the report is regenerated when it is printing or
when I change to another page in the previewwindow, so that the
changes made are cancelled.
How could I prevent the report to be regenerated after I changed the
text of the tppdrawcommands?
How could I save the previewed and changed report, so that I cann
reload it later, without generating it again, so that the changes
made, are permanent, until the user explicit generates the report new?
Helmut
"Am Tue, 24 Feb 2004 08:09:06 -0700, schrieb "Nico Cizik \(Digital
First, I must emphasize that this type of application is not what
ReportBuilder was designed to do. From experience, the more you ask of
ReportBuilder during or after report generation, the harder it gets to
obtain the results you want.
Keeping that in mind...
1. The reason setting zoomsetting := zoomsetting redraws the page is that
when you set the zoomsetting, the screen device renders the page again and
the page is refreshed. You can accomplish the same thing with essentially
less code by calling
Viewer.ScreenDevice.RenderPage;
Viewer.RefreshPage;
2. Simply changing the properties of the drawcommands will not affect the
actual report components, so when the report is printed or saved, you will
not see the changes. A workaround for this would be to change the actual
component properties by accessing the TppDrawCommand.Component property.
Below is some code I wrote to do just that. Hope this helps.
procedure TForm1.ppLabel1DrawCommandClick(Sender, aDrawCommand: TObject);
begin
TppDrawText(aDrawCommand).Text := 'Nico can''t code';
TppLabel(TppDrawText(aDrawCommand).Component).Text := 'Nico can''t code';
ppViewer1.ScreenDevice.RenderPage;
ppViewer1.RefreshPage;
end;
--
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com