Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Editing of report in Preview

edited February 2004 in General
Hello,

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.

Helmut

Comments

  • edited February 2004
    Hi Helmut,

    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.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2004
    Hi Nico,

    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
  • edited February 2004
    Hi 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.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2004
    Hi Nico,

    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
  • edited February 2004
    Hi Nico,

    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
  • edited February 2004
    Hi Nico,

    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
  • edited February 2004
    Hi 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;


    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2004
    Hi Nico,

    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;-)
  • edited February 2004
    Hi Helmut,

    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.

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2004
    Hi Nico,

    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
  • edited February 2004
    Hi Helmut,

    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;

    --
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
This discussion has been closed.