Hello there,...
My current software is running reports using DLLs that generates PDF files.
To ease report development, we wanted to add FR3 functionality to that. Meaning, the software would run external FR3 files from a specific folder.
All is working perfectly well except one thing, and a big one...
The host software connects to one database only, and we have several independant databases servers, meaning the FR3 report must therefore be able to run on the database object given by the host application.
My solution was to use a simple function like this one to change the database the report was based onto...:
procedure TForm2.SetFR3Object(strObjectName: string; pObject: Pointer);
Var intX: Integer;
begin
for intX := 0 to Pred (frxReport1.AllObjects.Count) do begin
If SameText(TComponent(frxReport1.AllObjects[intX]).Name,strObjectName) then begin
frxReport1.AllObjects[intX]:=pObject;
exit;
end;
end;
Raise Exception.Create('Object '+strObjectName+' not found.');
end;
procedure TForm2.FormCreate(Sender: TObject);
Var fodTemp: TfrxODACDatabase;
begin
fodTemp := GetFR3Object ('ODACDatabase1');
SetFR3Object('ODACDatabase1', Nil); // Just test the function by setting to Nil the ODACDatabase1 object from the FR file
SetFR3Object('ODACDatabase1', fodTemp); // And then restore backed up pointer
end;
This function compiles perfect, code seems ok... But... the line from SetFR3Object procedure:
frxReport1.AllObjects[intX]:=pObject;
does not do what it is supposed to do. The pointer does not change as expected!
In other words, how can I replace an ODAC database component from the report file (.FR3) loaded into memory with a TfrxODACDatabase created in my host application?
Thanks!
ODAC and Fast Reports...
You can change the properties of the TfrxODACDatabase component instead of replacing it. For example:
Code: Select all
procedure TForm1.SetFR3Object(strObjectName: string);
Var
intX: Integer;
begin
for intX := 0 to Pred (frxReport1.AllObjects.Count) do begin
If SameText(TComponent(frxReport1.AllObjects[intX]).Name, strObjectName) then begin
with TObject(frxReport1.AllObjects[intX]) as TfrxODACDatabase do begin
Server := 'new_server';
Username := 'new_name';
Password := 'new_pass';
end;
exit;
end;
end;
Raise Exception.Create('Object '+strObjectName+' not found.');
end;Hi Plash, and many thanks...
It works indeed. Just did the simple following code:
frxODACDatabase := TfrxODACDatabase(frxReport.FindObject (strFrxDatabaseName));
frxODACDatabase.Server := oraSession.Server;
frxODACDatabase.Username := oraSession.Username;
frxODACDatabase.Password := oraSession.Password;
I thought about replacing the object first because I believed this kind of code would have opened two active sessions, but it doesn't. It just opens one active session indeed (I've checked my Oracle active sessions).
By the way, for over 4 and a half year I am a customer, I needed your help three times, and three times my trouble was solved within the next day. Frankly, this is the best customer support I have ever experienced as a software developper, and this is really much appreciated!
Thanks! Thanks! Thanks!
It works indeed. Just did the simple following code:
frxODACDatabase := TfrxODACDatabase(frxReport.FindObject (strFrxDatabaseName));
frxODACDatabase.Server := oraSession.Server;
frxODACDatabase.Username := oraSession.Username;
frxODACDatabase.Password := oraSession.Password;
I thought about replacing the object first because I believed this kind of code would have opened two active sessions, but it doesn't. It just opens one active session indeed (I've checked my Oracle active sessions).
By the way, for over 4 and a half year I am a customer, I needed your help three times, and three times my trouble was solved within the next day. Frankly, this is the best customer support I have ever experienced as a software developper, and this is really much appreciated!
Thanks! Thanks! Thanks!