How can I display Crystal XI reports in a Delphi 2007 application?

The latest Crystal XI component for Delphi was released for Delphi 7. This VCL component compiles in D2007 but gives me runtime errors. What is the best way to display Crystal Reports in a database in a Delphi 2007 application?

+4
source share
5 answers

This is the solution I found using ActiveX:

First register the Active X element as follows:

In Delphi, select Component → Import Component

Click "Type Library", click "Next"

Select "Crystal ActiveX Report Viewer Library 11.5"

Select any page of the palette that you want (I went to "Data Access")

Choose an import location

Exit the wizard

Add the location that you selected in your path to the project.

Now this code should work:

... uses CrystalActiveXReportViewerLib11_5_TLB, OleAuto; ... procedure TForm1.Button1Click(Sender: TObject); var cry : TCrystalActiveXReportViewer; oRpt, oApp : variant; i : integer; frm : TForm; begin cry := TCrystalActiveXReportViewer.Create(Self); oApp := CreateOleObject('CrystalRuntime.Application'); oRpt := oApp.OpenReport('c:\my_report.rpt',1); for i := 1 to oRpt.Database.Tables.Count do begin oRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := 'username'; oRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := 'password'; end; frm := TForm.Create(Self); try cry.Parent := frm; cry.Align := alClient; cry.ReportSource := oRpt; cry.ViewReport; frm.Position := poOwnerFormCenter; frm.ShowModal; finally FreeAndNil(frm); end; //try-finally end; procedure TForm1.btnExportClick(Sender: TObject); var cry : TCrystalActiveXReportViewer; oRpt, oApp : variant; i : integer; begin //Export the report to a file cry := TCrystalActiveXReportViewer.Create(Self); oApp := CreateOleObject('CrystalRuntime.Application'); oRpt := oApp.OpenReport(c_DBRpt,1); for i := 1 to oRpt.Database.Tables.Count do begin oRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := 'username'; oRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := 'password'; end; oRpt.ExportOptions.FormatType := 29; //excel 8 oRpt.ExportOptions.DiskFileName := 'c:\output.xls'; oRpt.ExportOptions.DestinationType := 1; //file destination //Export(False) => do NOT prompt. //Export(True) will give runtime prompts for export options. oRpt.Export(False); end; 

If you use this method, then this (rather dense) link will be useful, especially since Intellisense does not work on Ole objects like them.

Edit: The original link to the link has broken, so I changed it to a new one (valid from December 15, 2009). If this new one breaks, then Google should find it .

+4
source

I know this is not your question, and this may not be an acceptable answer at all in your situation, but I found FastReports clearly superior to Crystal for my purposes. It has lighter weight, includes a real scripting language, includes event processing, allows you to make calls to your own code for information and updates, and does not require an ActiveX connection. I can export my reports to interesting PDF files or Excel spreadsheets and several other formats. The quality of the result adds to the overall experience that users get from my application. I could go on, but if this is not for you, it will not help.

+3
source

For anyone who can use it, here is a complete class that gives a nice wrapper around these nasty Crystal interactions. It works for me in about 80% of cases, but I suspect that many of these materials are very dependent on the specific platform on which it works. I will post the improvements when I create them.

Someone from Business Objects should really carefully study this API. It sucks bad.

 { Class to facilitate the display of Crystal 11 Reports. The Crystal 11 VCL component does not seem to work with Delphi 2007. As a result, we have to use ActiveX objects, which make deployment messy. This class is similar to CrystalReporter, but it works for Crystal 11. However, it lacks some of the features of the old CrystalReporter. Refer to the crystal reports activex technical reference to duplicate the missing functionality. Example usage is at the bottom of this unit. //} unit CrystalReporter11; interface uses CrystalActiveXReportViewerLib11_5_TLB, OleAuto, Classes, Controls; type TCryExportFormat = ( XLS ,PDF ); type TCrystalReporter11 = class private FCryRpt : TCrystalActiveXReportViewer; FRpt, FApp : variant; FReportFile, FUsername, FPassword, FServer, FFilters : string; FOwner : TComponent; procedure SetLoginInfo(const username, password, server : string); function GetFilterConds: string; procedure SetFilterConds(const Value: string); public property FilterConditions : string read GetFilterConds write SetFilterConds; procedure ExportToFile(ExportFileName : string; FileExportFmt : TCryExportFormat; PromptForOptions : boolean); procedure Display; constructor Create(AOwner : TComponent; ReportFile : string); overload; constructor Create(AOwner : TComponent; ReportFile, Username, Password, Server : string); overload; end; implementation uses SysUtils, Forms; const //these are taken from pgs 246 and 247 of the technical reference c_FmtCode_Excel = 29; c_FmtCode_PDF = 31; constructor TCrystalReporter11.Create(AOwner: TComponent; ReportFile: string); begin inherited Create; try FReportFile := ReportFile; if FileExists(FReportFile) then begin FOwner := AOwner; FCryRpt := TCrystalActiveXReportViewer.Create(AOwner); FApp := CreateOleObject('CrystalRuntime.Application'); FRpt := FApp.OpenReport(FReportFile,1); FFilters := FRpt.RecordSelectionFormula; end else begin raise Exception.Create('Report file ' + ReportFile + ' not found!'); end; except on e : exception do raise; end; //try-except end; constructor TCrystalReporter11.Create(AOwner: TComponent; ReportFile, Username, Password, Server: string); begin Create(AOwner,ReportFile); FUsername := Username; FPassword := Password; FServer := Server; SetLoginInfo(FUsername,FPassword,FServer); end; procedure TCrystalReporter11.Display; var rptForm : TForm; begin SetLoginInfo(FUsername,FPassword,FServer); FCryRpt.ReportSource := FRpt; rptForm := TForm.Create(FOwner); try FCryRpt.Parent := rptForm; FCryRpt.Align := alClient; FCryRpt.ViewReport; rptForm.Position := poOwnerFormCenter; rptForm.WindowState := wsMaximized; rptForm.Caption := ExtractFileName(FReportFile); rptForm.ShowModal; finally FreeAndNil(rptForm); end; //try-finally end; procedure TCrystalReporter11.ExportToFile(ExportFileName : string; FileExportFmt : TCryExportFormat; PromptForOptions : boolean); begin case FileExportFmt of XLS : FRpt.ExportOptions.FormatType := c_FmtCode_Excel; PDF : FRpt.ExportOptions.FormatType := c_FmtCode_PDF; end; //case FRpt.ExportOptions.DiskFileName := ExportFileName; FRpt.ExportOptions.DestinationType := 1; //file destination FCryRpt.ReportSource := FRpt; FRpt.Export(PromptForOptions); end; function TCrystalReporter11.GetFilterConds: string; begin Result := FFilters; end; procedure TCrystalReporter11.SetFilterConds(const Value: string); begin FFilters := Value; if 0 < Length(Trim(FFilters)) then begin FRpt.RecordSelectionFormula := Value; end; end; procedure TCrystalReporter11.SetLoginInfo(const username, password, server : string); var i : integer; begin //set user name and password //crystal only accepts these values if they are CONST params for i := 1 to FRpt.Database.Tables.Count do begin FRpt.Database.Tables[i].ConnectionProperties.Item['User ID'] := username; FRpt.Database.Tables[i].ConnectionProperties.Item['Password'] := password; try { Some reports use direct connections, and others use an ODBC Data Source. Crystal XI uses a different label to refer to the database name in each method. I don't know how to determine in advance which method is being used, so: First, we try the direct connection. If that fails, we try the "data source" method. Reference: "Crystal Reports XI Technical Reference", pages 41 thru 46; "Common ConnectionProperties" } FRpt.Database.Tables[i].ConnectionProperties.Item['Server'] := server; except on E: Exception do FRpt.Database.Tables[i].ConnectionProperties.Item['Data Source'] := server; end; end; end; { Example usage: procedure TForm1.btnShowRptDBClick(Sender: TObject); var cry : TCrystalReporter11; begin cry := TCrystalReporter11.Create(Self,'c:\my_report.rpt','username', 'password','server.domain.com'); try cry.Display; finally FreeAndNil(cry); end; end; } end. 
+3
source

I, too, was disappointed at Crystal Reports' lack of effort regarding application integration. I use RDC, and from what I understand, it is deprecated, and the emphasis is on .Net.

My application has these files in the uses clause: CRRDC, CRAXDRT_TLB,

It is working fine. The disadvantage is the transfer of parameters. In my option, the options dialog boxes that come with the viewer are terrible. Therefore, I use my own Delphi application to request parameters and pass them to the report.

+1
source

Here is a slightly simpler and cleaner class that solves the problem very well:

Unit CrystalReports; uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.OleCtrls, ActiveX, ComObj, Data .DB, Data.Win.ADODB, CrystalActiveXReportViewerLib11_TLB, Vcl.OleServer, CrystalReportsControllersLib_TLB;

 type TCrystalReportForm = class(TForm) CRV: TCrystalActiveXReportViewer; procedure DisplayReport; private { Private declarations } public {Public declarations } ReportName : WideString; ReportCaption : String; ReportSelectionFormula : WideString; end; var CRXIRuntime : Variant; implementation {$R *.dfm} procedure TCrystalReportForm.DisplayReport; var CrystalReport : variant; i : integer; begin CrystalReport := CRXIRuntime.OpenReport(ReportName); for i := 1 to CrystalReport.Database.Tables.Count do begin CrystalReport.Database.Tables[1].ConnectionProperties.Item['User ID'] := 'user'; CrystalReport.Database.Tables[1].ConnectionProperties.Item['Password'] := 'password'; end; CrystalReport.FormulaSyntax := 0; Caption := ReportCaption; CrystalReport.RecordSelectionFormula := ReportSelectionFormula; CRV.Align := alClient; CRV.ReportSource := CrystalReport; WindowState := wsMaximized; CRV.ViewReport; ShowModal; end; begin CRXIRuntime := CreateOleObject('CrystalRuntime.Application'); end. 
0
source

All Articles