Create PDF / Print Report from Windows Service Applicattion
In one of our applications we use a Windows Service to perform some daily
tasks on the database. We are trying to extend this Windows Service to print
a report or to create a PDF from the report.
The complete process to create this documenten is a separte Thread object
which at this moment is called from the "normal desktop" application on one
of the customers computers. When we integrate the Thread object in our
service application everything is initialised in a normal way. Only when the
UserReport.Print procudure is executed an Errormessage appears in our log
"Databasename can't be empty". This errormessage isn't there when the Thread
is execute from the desktop application.
For the complete overview, our Windows Service application executes a
separete Thread for each task. All the tasks which import files in the
database, export a fiel direct from the database or send E-mail though Indy
are working fine, only when output from Reportbuilder is needed this
errormessage is there.
Below an overview of the code
UserReport.Template.DatabaseSettings.Name :=
SQLDepartment.FieldByName('TemplateName').AsString;
UserReport.Template.LoadFromDatabase;
UserReport.ShowAutoSearchDialog := False;
UserReport.ShowPrintDialog := False;
UserReport.ShowCancelDialog := False;
UserReport.DeviceType := 'Printer';
UserReport.PrinterSetup.BinName :=
SQLDepartment.FieldByName('PaperBinOffline').AsString
UserReport.OnGetAutoSearchValues := GetSearchValues;
UserReport.Print;
procedure ThPrint.GetSearchValues(Sender: TObject);
var index: byte;
begin
try
CreateLog('Set Searchcriteria','AutoPrintReport');
if UserReport.AutoSearchFieldCount <= 0 then exit;
for index:=0 to UserReport.AutoSearchFieldCount-1 do
begin
if
UpperCase(UserReport.AutoSearchFields[index].FieldName)='ONDERHOUDID'
then UserReport.AutoSearchFields[index].SearchExpression :=
StrOnderhoudID
else UserReport.AutoSearchFields[index].DisableCriteria;
end;
CreateLog('Searchcriteria is
set:'+UserReport.AutoSearchFields[index].SearchExpression,'AutoPrintReport');
except
on E : Exception do
CreateLog('Error PrinterServer
Thread:'+E.Message,'AutoPrintReport');
end;
end;
The Data and the reports are stored in a Firebird 1.5 database. The Delphi
Version is 2005 and the Report Builder version is 11.08. IB_Objects 4.9.10
is used to connect to the database
tasks on the database. We are trying to extend this Windows Service to print
a report or to create a PDF from the report.
The complete process to create this documenten is a separte Thread object
which at this moment is called from the "normal desktop" application on one
of the customers computers. When we integrate the Thread object in our
service application everything is initialised in a normal way. Only when the
UserReport.Print procudure is executed an Errormessage appears in our log
"Databasename can't be empty". This errormessage isn't there when the Thread
is execute from the desktop application.
For the complete overview, our Windows Service application executes a
separete Thread for each task. All the tasks which import files in the
database, export a fiel direct from the database or send E-mail though Indy
are working fine, only when output from Reportbuilder is needed this
errormessage is there.
Below an overview of the code
UserReport.Template.DatabaseSettings.Name :=
SQLDepartment.FieldByName('TemplateName').AsString;
UserReport.Template.LoadFromDatabase;
UserReport.ShowAutoSearchDialog := False;
UserReport.ShowPrintDialog := False;
UserReport.ShowCancelDialog := False;
UserReport.DeviceType := 'Printer';
UserReport.PrinterSetup.BinName :=
SQLDepartment.FieldByName('PaperBinOffline').AsString
UserReport.OnGetAutoSearchValues := GetSearchValues;
UserReport.Print;
procedure ThPrint.GetSearchValues(Sender: TObject);
var index: byte;
begin
try
CreateLog('Set Searchcriteria','AutoPrintReport');
if UserReport.AutoSearchFieldCount <= 0 then exit;
for index:=0 to UserReport.AutoSearchFieldCount-1 do
begin
if
UpperCase(UserReport.AutoSearchFields[index].FieldName)='ONDERHOUDID'
then UserReport.AutoSearchFields[index].SearchExpression :=
StrOnderhoudID
else UserReport.AutoSearchFields[index].DisableCriteria;
end;
CreateLog('Searchcriteria is
set:'+UserReport.AutoSearchFields[index].SearchExpression,'AutoPrintReport');
except
on E : Exception do
CreateLog('Error PrinterServer
Thread:'+E.Message,'AutoPrintReport');
end;
end;
The Data and the reports are stored in a Firebird 1.5 database. The Delphi
Version is 2005 and the Report Builder version is 11.08. IB_Objects 4.9.10
is used to connect to the database
This discussion has been closed.
Comments
From the information below, it seems like the error is occurring with the
individual template data access. Are you using DADE to connect these
templates to data? If so, I suggest using a TppDesigner at run time to take
a look at the template's data workspace during runtime and see if the
datasetttings are properly assigned.
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
As you stated I use the DADE tab within the designer to specify the data
I have included a ppDesigner component and added the following extra lines
of code in the intialisation of the Thread after the creation of the
UserReport (ppReport)
ppDesigner1:=TppDesigner.Create(ppDesigner1);
ppDesigner1.Report:=UserReport;
ppDesigner1.DataSettings.AllowEditSQL:=True;
ppDesigner1.DataSettings.DatabaseType:=dtInterBase;
ppDesigner1.DataSettings.DatabaseName:=TCDB.Databasename
ppDesigner1.DataSettings.SessionType:='IBOSession';
ppDesigner1.DataSettings.SQLType:=sqSQL2;
When I Load the template into the UserReport (ppReport) and check the value
of ppDesigner1.Datasettings.DatabaseName it is empty
UserReport.Template.DatabaseSettings.Name :=
SQLAfdeling.FieldByName('TemplateWerkbon').AsString;
UserReport.Template.LoadFromDatabase;
CreateLog(ppDesigner1.DataSettings.DatabaseName,'AutoPrintWerkbon');
In the mainapplication the Database (TCDB) is located on a separate Form
with some database tools.
On the MainForm a Report, Designer and ReportExplorer are placed to edit all
the different reports in the application
The strange point is when I use the Thread in our main application(from the
userdesktop) The same lines of code are used. In this thread a new
Databasecomponent is created with the name DBConnection. In this setup
everything is working OK.
Is there a way to make an addional initialisation of the datasetting after
the template is loaded into the ppReport
Best Regards,
Vincent Schuurhuis
Maneffic Solutions
You must provide a thread-safe container for the report to execute. The
container should be a TDataModule upon which the Report resides. The
container must provide a thread-safe database connection. On the TDataModule
you must have a database connection component that has the same name as the
one you used to create the DADE query. (The DataSettings such as the
DatabaseName are saved as part of the query definition.)
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com