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

pipeline afteropen fires although opendataset false

edited October 2012 in Datapipelines
Hi,

we are moveinf from delphi7 to delphiXE2. In the delphi7 environment we use
the pipeline afteropen event to display a selection dialog. This always
worked ok.

The difference i found is that in procedure TppDBPipeline.GetFieldDataType,
Open is called. This triggers Beforeopen etc. In the delphi7 version
"Opendataset" is called. Bypassing the events.

Because we have multiple pipelines on a form. All before and after open
events fire when the form is created. Is this a bug or changed intentionaly?
Can i reverse this by calling OpenDataSet instead of Open?

Kind Regards

Ruud

Comments

  • edited October 2012
    L.S.

    In addition to this in some situations the reportExplorer or reportviewer
    freezes.
    In the datapipeline afteropenevent i open a form like this:

    line 1 frmselmedroosterweken :=tfrmselMedRoosterweken.create(self);
    line 2 frmselmedroosterweken.ShowModal;
    line 3 frmselmedroosterweken.Free;

    I put a tracepoint on line 1. The program stops there. Started again the
    program never reaches line 2.
    When i put a trace point in formcreate of the created form it never reaches
    that point either.

    Can you give me a hint what is going wrong?

    Kind Regards

    Ruud


  • edited October 2012
    Hi Ruud,

    Which version of ReportBuilder are you using and which version are you
    upgrading from?

    For later versions of ReportBuilder we added the
    Report.OnBeforeOpenDatapipelines and OnAfterOpenDatapipelines events
    that may be useful in your case.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    Hi Ruud,

    Which version of ReportBuilder are you using?

    Are you able to recreate this with the main end-user demo included with
    ReportBuilder? If not, please send a simple example I can run here that
    demonstrates the issue in .zip format and I'll take a look at it for
    you. Send the example to support@digital-metaphors.com.


    Best Regards,

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

    We are using the latest version 14.06 and are already using
    OnBeforeOpenDatapipelines and OnAfterOpenDatapipelines.

    The problem is that these events fire although opendataset is set to
    false. TppDBPipeline.GetFieldDataType fires the event but should not
    because the dataset is not being opened due to opendataset.

    Regards

    Ruud


    Op 22-10-2012 15:16, Nico Cizik (Digital Metaphors) schreef:
  • edited October 2012
    Hi Ruud,

    If I understand correctly, you are using Rb 14.06 for both Delphi 7 and
    Delphi XE. When using Delphi 7, it behaves as expected, but when using
    XE, the pipeline events fire differently.

    I'm trying to isolate exactly what has changed since the time your app
    behaved correctly so I can take a look at what may have changed.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    In Delphi7 we use an older version. 9.03

    the difference is in ppDBPipe.pas TppDBPipeline.GetFieldDataType

    9.03 : calls Opendataset

    function TppDBPipeline.GetFieldDataType(aFieldName: String): TppDataType;
    begin

    {try using TppField info, if not auto create fields}
    if not AutoCreateFields then
    Result := inherited GetFieldDataType(aFieldName)
    else
    Result := dtNotKnown;

    if (Result <> dtNotKnown) then Exit;

    {try to use TField info}
    if not(Active) then
    try
    OpenDataSet;
    except

    end;

    if SetCurrentField(aFieldName) then
    Result := ppConvertFieldType(FFieldDataLink.Field.DataType);

    end; {function, GetFieldDataType}

    procedure TppDBPipeline.OpenDataSet;
    begin

    if (FDataSet <> nil) and (csDestroying in FDataSet.ComponentState)
    then Exit;

    FDataSet := FDataLink.DataSet;

    if (FDataSet <> nil) then
    FDataSet.FreeNotification(Self);

    if FOpenDataSource and (FDataLink.DataSet <> nil) then
    try
    FDataLink.DataSet.Open;
    except on E: Exception do
    raise EDataError.Create(E.Message);
    end;

    end; {procedure, OpenTheDataPipeline}


    14.06: calls Open

    function TppDBPipeline.GetFieldDataType(aFieldName: String): TppDataType;
    begin

    Result := dtNotKnown;

    // optimization, use TppField if possible
    if SetFieldName(aFieldName) then
    Result := CurrentField.DataType;

    if (Result = dtNotKnown) then
    begin

    {try using TppField info, if not auto create fields}
    if not AutoCreateFields then
    Result := inherited GetFieldDataType(aFieldName)
    else
    Result := dtNotKnown;

    if (Result <> dtNotKnown) then Exit;

    {try to use TField info}
    if not(Active) then
    try
    Open;
    except

    end;

    if SetCurrentField(aFieldName) then
    Result := ppConvertFieldType(FFieldDataLink.Field.DataType);

    end;

    end; {function, GetFieldDataType}

    procedure TppDataPipeline.Open;
    begin

    DoBeforeOpen;

    OpenDataSet;

    UpdateState;

    DoAfterOpen;

    end;

    The effect is that 14.06 fires the open events on creation 9.03 does not.

    Regards Ruud




    Op 22-10-2012 17:34, Nico Cizik (Digital Metaphors) schreef:
  • edited October 2012
    Ruud,

    Thank you. For future reference, please give us the exact versions you
    are using and upgrading from to make it easier for us to understand the
    differences.

    This code was changed on purpose to stay more consistent within the
    pipeline. In my testing however with a simple example (two datasets,
    datasources, and pipelines connected to a single report with DBText
    components). The OnBeforeOpen or OnAfterOpen events do not fire until
    the report is printed. No pipeline events are fired when the form is
    created which means that the GetFieldDataType/GetFieldValue routines are
    not executing either.

    If possible, please send me a simple example demonstrating the behavior
    you describe in .zip format to support@digital-metaphors.com and I'll
    take a look at it for you. Possibly use the DBDEMOS database to create
    this example.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    Which demo uses datasets and datapipelines?


  • edited October 2012
    Ruud,

    Most of the main report demos use pipelines and datasets. A simple
    example from scratch should however be very simple to create using a
    couple TQueries, TDatasource, and TppDBPipeline components and a TppReport.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    Hi Nico

    I took the Delphi XE2\Demos\3. EndUser\1. Report Explorer\Enduser
    program and added extra tables and pipelines.
    The tables are not active and the pipelines have opendatasource=false.
    The open and close pipelineevents have a messagedialog.

    On startop the messages apear. I mailed the modified demo's

    Kind regards

    Ruud


  • edited October 2012

    Thanks for providing the example.

    To correct the example, double-click each DataPipeline to access the fields
    editor. Then close the fields editor and set DataPipeline.AutoCreateFields
    to False. Doing this will create static TppField objects that are
    saved/loaded with the form.

    That demo is configured to run in a unique manner. In the project source
    there is code to suppress displaying the application main form. In the
    FormCreate a Timer is set. In the TimerEvent a call is made to
    ReportExplorer.Execute. The ReportExplorer initializes the Designer. At this
    point the designer data tree initializes with a list of that datapipelines
    and fields. The datapipelines in your example have AutoCreateFields set to
    True, this requires opening the datapipelines.

    Here is the relative code

    The project source code...

    Application.MainForm.Visible := False;
    Application.ShowMainForm := False;


    The FormCreate event code that sets a TTimer....

    FTimer := TTimer.Create(Self);
    FTimer.Interval := 100;
    FTimer.OnTimer := TimerEvent;

    In the TimerEvent there is code to execute the report explorer....


    procedure TmyEndUserSolution.TimerEvent(Sender: TObject);
    var
    lsMessage: String;
    begin

    FTimer.Free;

    if not(ppReportExplorer1.Execute) then
    begin
    lsMessage := 'Error: ' + ppReportExplorer1.ErrorMessage;

    MessageDlg(lsMessage, mtError, [mbOK], 0);
    end;

    Application.Terminate;

    end; {procedure, TimerEvent}



    -
    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited October 2012
    Hi Nard,

    Thanks for looking in to this. Our application works kind alike. In fact
    this example was the inspiration years ago.

    It never was a problem in reportbuilder 9.04 and several version prior
    to that, due to the fact that in function TppDBPipeline.GetFieldDataType
    opendataset was called instead of open.

    Nico already wrote ?This code was changed on purpose to stay more
    consistent within the pipeline.?

    If I change it back to opendataset, it seems to work for us. Or can I
    expect big problems by doing so? Can you be more precise why you changed it?

    Thanx in advance

    Ruud



  • edited October 2012

    From a logical/design standpoint, the DataPipeline should only call
    OpenDataSet from DataPipeline.Open. Customers reported the prior behavior as
    a bug because the DataPipeline is closed but opens the dataset - that make
    no sense. In addition, customers expect BeforeOpen to be called before the
    dataset is opened.

    If you want the designer to ignore the DataPipelines on your form, you could
    try setting DataPipeline.Visible to False.

    If you statically create the fields as I described before, then the example
    you provided works.

    If you want to change the source code, that is not the approach I recommend
    or the approach I would take myself, but I don't think it will cause an
    issue.


    -
    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited October 2012
    Hi Nard,

    If i set the datapipeline.visibility to false. The user wont be able to
    choose it in the designer anymore.

    Creating datapipeline fields statically is not an easy option either. We
    have lots of forms with multiple pipelines. Each time the dataset is
    altered i have to open the print form and alter the datapipeline.

    I stick to the way it worked before and check the opendataset property.

    thanks again, for looking in to this.


    kind regards,

    Ruud




This discussion has been closed.