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

Create PDF / Print Report from Windows Service Applicattion

edited August 2010 in General
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

Comments

  • edited August 2010
    Hi Vincent,

    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

    Best Regards,

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

    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

  • edited August 2010

    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
This discussion has been closed.