BDE to IBO conversion
Delphi 7, Report Builder 10.06
I am in the process of converting an app, that was designed to utilize the
BDE to access a firebird DB, to utilize IBObjects to access the firebird DB.
I am having some serious issues with my End User Reporting solution after I
have converted it to IBO.
I have another app that was created from the beginning to utilize IBO to
access a firebird DB which works great! So to make sure that I didn't have
any issues with the way I converted the other app to IBO, I decided to
change the DB component of the app that I know works with IBO to the DB of
the app that was previously utilizing the BDE. I receive several errors
that render all existing reports useless.
When I try to design any of the existing reports, open any of the existing
reports, or load from file a report template of any of the reports created
via the BDE app I get the following error message in Delphi:
Project ReportApp.exe raised exception class EReadError with message
'Invalid property value'. Process stopped. Use Step or Run to continue.
This error ocurrs on line 1172 of ppTmplat.pas which is
lReader.ReadComponents(FRoot, nil, LoadCallback);
I then click run in Delphi and get another error message:
Project ReportApp.exe raised exception class EReadError with message
'Error reading RBReport.BeforeAutoSearchDialogCreate:
Invalid property value'. Process stopped. Use Step or Run to continue.
I then click run again and get the previous error (Error reading
RBReport.BeforeAutoSearchDialogCreate: Invalid property value) on an
error/message dialog from the report application.
I decided to try and manually move the report information over by exporting
the dataviews to file and copying the report components into a new report.
When I attampted to import from file the data views of a report that was
created via the BDE app I received the followong error:
Class TdaBDEQueryDataView not found
Is there a way to convert reports created via the BDE (daBDE) to run via IBO
(daIBO)?
Thanks All,
Branden Johnson
I am in the process of converting an app, that was designed to utilize the
BDE to access a firebird DB, to utilize IBObjects to access the firebird DB.
I am having some serious issues with my End User Reporting solution after I
have converted it to IBO.
I have another app that was created from the beginning to utilize IBO to
access a firebird DB which works great! So to make sure that I didn't have
any issues with the way I converted the other app to IBO, I decided to
change the DB component of the app that I know works with IBO to the DB of
the app that was previously utilizing the BDE. I receive several errors
that render all existing reports useless.
When I try to design any of the existing reports, open any of the existing
reports, or load from file a report template of any of the reports created
via the BDE app I get the following error message in Delphi:
Project ReportApp.exe raised exception class EReadError with message
'Invalid property value'. Process stopped. Use Step or Run to continue.
This error ocurrs on line 1172 of ppTmplat.pas which is
lReader.ReadComponents(FRoot, nil, LoadCallback);
I then click run in Delphi and get another error message:
Project ReportApp.exe raised exception class EReadError with message
'Error reading RBReport.BeforeAutoSearchDialogCreate:
Invalid property value'. Process stopped. Use Step or Run to continue.
I then click run again and get the previous error (Error reading
RBReport.BeforeAutoSearchDialogCreate: Invalid property value) on an
error/message dialog from the report application.
I decided to try and manually move the report information over by exporting
the dataviews to file and copying the report components into a new report.
When I attampted to import from file the data views of a report that was
created via the BDE app I received the followong error:
Class TdaBDEQueryDataView not found
Is there a way to convert reports created via the BDE (daBDE) to run via IBO
(daIBO)?
Thanks All,
Branden Johnson
This discussion has been closed.
Comments
to any conversion...
-------------------------------------------------
Tech Tip: Convert BDE Template Dataviews To ADO
-------------------------------------------------
Currently when DADE is used to create dataviews, the DatabaseName is stored
as part of the query definition. (This is consistent with Delphi's approach
to specifying a database connection for a Query object).
When you created the reports originally, the daDBBDE.pas BDE DADE plugin was
used. Now you want to use ADO. You've already changed the
Designer.Datasettings but this had no effect on the old reports. They still
try to use the BDE connection. Changing the Designer.DAtaSettings only works
for new dataviews that are created, because the new query dataviews are
using the daADO.pas ADO DADE plugin.
In order to convert the templates from BDE to ADO, at the minimum you have
to change the database name and the DADE plugin class names that are stored
in the templates. When a BDE dataview is created, its class type is a
TdaBDEQueryDataview. When an ADO dataview is created, its class type is
TdaADOQueryDataview. These class types are stored in the template. These
have to be changed before the template is loaded into a report.
First, compare a BDE report template to an ADO report template which both
connect to the same database table. Save a BDE and an ADO based report
template to separate ASCII text files. Now compare the dataview definitions.
Change the TdaBDEQueryDataview class name to TdaADOQueryDataview in the BDE
template. Change the BDE alias to your ADOConnection object. Then compare
the table name and field names of the BDE template to the ADO template and
change them accordingly, removing the .db extension on the table name is
necessary. Now load the converted BDE template in your ADO end user
application.
The first step is to make a backup of all your templates before continuing
with a programatic approach. You can convert the templates programatically
by loading the ASCII template files to a TStringList object. Then loop
through the lines of the list and change the text programatically. You can
loop through the files in a directory using ppFileUtils.pas calling the
GetFileNamesForDirectory procedure to load the file names.
If you have binary report templates, you'll also be able to convert these
with an extra couple of steps. You can load the binary template file into
ASCII format, modify it, and then save it back to binary as shown in the
example links below. Keep in mind the conversion is performed without
loading the report template into a TppReport.
This example shows how to load reports stored to the ReportExplorer database
tables and convert them to ascii text.
http://www.digital-metaphors.com/tips/EditTemplatesAsText.zip
This example shows how to convert an .rtm file to asii text
http://www.digital-metaphors.com/tips/ConvertBinaryTemplateToASCII.zip
--
Tech Support mailto:support@digital-metaphors.com
Digital Metaphors http://www.digital-metaphors.com
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
The example worked. I have migrated the code to my app so that I can use
the a TIBO table and my DB connection to convert the reports. I have also
combined the procedures LoadTemplate and SaveTemplate so that I can run one
procedure that will iterate through the report records, load the templates
into the memo component (memTemplate), convert the template text, and save
the template back to the DB.
I am getting an access violation in the line:
memTemplate.Lines.LoadFromStream(lTextStream);
I am not sure why I would be getting this access violation? Any ideas?
Thank you,
Branden Johnson
Here is my full code for the procedure:
procedure TfrmMain.ConvertReportstoIBO1Click(Sender: TObject);
const
cReport = 1;
var
liItemID: Integer;
lBinaryStream: TMemoryStream;
lTextStream: TMemoryStream;
lWriter: TWriter;
memTemplate: TMemo;
I: Integer;
sLine: String;
begin
plItem.Open;
plItem.First;
while not plItem.EOF do
begin
{check that item type is a report}
if plItem['Item_Type'] = Ord(cReport) then
begin
lBinaryStream := TMemoryStream.Create;
lTextStream := TMemoryStream.Create;
try
{read the binary stream from the database}
plItem.GetFieldAsStream('Template', lBinaryStream);
lBinaryStream.Position := 0;
{convert the binary stream to text}
ObjectBinaryToText(lBinaryStream, lTextStream);
lTextStream.Position := 0;
{load the text stream to the memo control}
memTemplate.Lines.LoadFromStream(lTextStream);
{Replace the class declarations and database}
for I := 0 to memTemplate.Lines.Count - 1 do
begin
sLine := memTemplate.Lines[I];
sLine :=
AnsiReplaceStr(sLine,'daBDEQueryDataView','daIBOQueryDataView');
sLine :=
AnsiReplaceStr(sLine,'TppChildBDEPipeline','TppChildDBPipeline');
sLine := AnsiReplaceStr(sLine,'dbMain','euDatabase');
memTemplate.Lines[I] := sLine;
end;
{load the memo control to the text stream}
memTemplate.Lines.SaveToStream(lTextStream);
lTextStream.Position := 0;
{convert the binary stream to text}
ObjectTextToBinary(lTextStream, lBinaryStream);
lBinaryStream.Seek(0,soFromEnd);
lWriter := TWriter.Create(lBinaryStream, 1024);
try
lWriter.Root := Self;
lWriter.WriteListEnd;
finally
lWriter.Free;
end;
lBinaryStream.Position := 0;
plItem.Edit;
{load the binary stream from the database}
plItem.SetFieldFromStream('Template', lBinaryStream);
plItem.Post;
finally
lBinaryStream.Free;
lTextStream.Free;
end;
end;
plItem.Next;
end;
end;
worked fine so then I copied the main form from the example to my app and
that is working.