pipeline afteropen fires although opendataset false
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
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
This discussion has been closed.
Comments
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
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.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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:
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.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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:
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.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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.
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
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
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
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