4 Stimmen

Wie kann ich Crystal XI-Berichte in einer Delphi 2007-Anwendung anzeigen?

Die neueste Crystal XI-Komponente für Delphi wurde für Delphi 7 veröffentlicht. Diese VCL-Komponente kompiliert in D2007, gibt mir aber zur Laufzeit Fehler. Wie kann ich einen mit der Datenbank verbundenen Crystal-Bericht in einer Delphi 2007-Anwendung am besten anzeigen?

4voto

JosephStyons Punkte 55410

Dies ist die Lösung, die ich mit ActiveX gefunden habe:

Registrieren Sie zunächst das Active X-Steuerelement wie folgt:

Wählen Sie in Delphi Komponente -> Komponente importieren

Klicken Sie auf "Typ Bibliothek", klicken Sie auf Weiter

Wählen Sie "Crystal ActiveX Report Viewer Library 11.5".

Wählen Sie die gewünschte Palettenseite (ich habe mich für "Data Access" entschieden)

Wählen Sie einen Importort

Verlassen des Assistenten

Fügen Sie den von Ihnen gewählten Ort zu Ihrem Projekt hinzu Suchpfad

Jetzt sollte dieser Code funktionieren:

...
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;

Wenn Sie diese Methode verwenden, dann diese (ziemlich dichte) Referenz hilfreich sein, zumal Intellisense bei Ole-Objekten wie diesen nicht funktioniert.

Edit: Der ursprüngliche Link zu der Referenz ist kaputt, also habe ich ihn geändert, um auf eine neue Referenz zu verweisen (gültig ab 15. Dezember 2009). Wenn dieser neue Link nicht funktioniert, dann Google sollte es finden können .

0 Stimmen

Jede Idee, was zu tun, wenn der CreateOleObject-Aufruf oben fehlschlägt? (EOleSysError :Ungültiger Klassenstring)

0 Stimmen

Offensichtlich sind die ActiveX-Steuerelemente veraltet und in den neueren Versionen des Systems nur noch halbwegs funktionsfähig. QUELLE: scn.sap.com/thread/1623428

3voto

jrodenhi Punkte 2209

Ich weiß, dass es nicht Ihre Frage ist und dass es in Ihrer Situation vielleicht überhaupt keine akzeptable Antwort ist, aber ich habe festgestellt, dass FastReports für meine Zwecke eindeutig besser ist als Crystal. Es ist leichter, enthält eine echte Skriptsprache, beinhaltet eine Ereignisbehandlung, kann für Informationen und Aktualisierungen Aufrufe in Ihren eigenen Code machen und benötigt keine ActiveX-Verbindung. Ich kann meine Berichte in ansprechende PDF-Dateien, Excel-Tabellen und verschiedene andere Formate exportieren. Die Qualität der Ausgabe trägt zum Gesamterlebnis bei, das die Benutzer mit meiner Anwendung haben. Ich könnte noch mehr sagen, aber wenn es für Sie nicht zum Thema passt, wird es nicht hilfreich sein.

2 Stimmen

Ich muss Crystal aus alten Gründen verwenden, aber danke für den Tipp. Ich habe gemischte Gefühle gegenüber Crystal. Einerseits kann man damit fast alles machen. Andererseits habe ich immer das Gefühl, dass ich es überreden muss, das zu tun, was ich will.

0 Stimmen

Ich habe immer das Gefühl, dass ich ihn überzeugen muss, das zu tun, was ich will. !! Es ist so schlimm?

3voto

JosephStyons Punkte 55410

Für alle anderen, die es gebrauchen können, ist hier eine vollständige Klasse, die eine angenehme Hülle um diese abscheulichen Crystal-Interaktionen bietet. Es funktioniert für mich etwa 80% der Zeit, aber ich vermute, eine Menge von diesem Zeug ist sehr abhängig von der spezifischen Plattform, auf der es läuft. Ich werde Verbesserungen posten, sobald ich sie mache.

Jemand bei Business Objects sollte sich diese API wirklich genau ansehen. Sie ist ziemlich ätzend.

{
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.

0 Stimmen

Hervorragend, außer dass dies in den letzten Jahren der Nutzung ist und in Kürze aus dem Produkt entfernt werden soll, wie aus einigen Forenbeiträgen bei SAP hervorgeht.

1voto

M Schenkel Punkte 6119

Auch ich war enttäuscht über die mangelnden Bemühungen von Crystal Reports im Hinblick auf die Anwendungsintegration. Ich verwende das RDC, und soweit ich weiß, wird dieses veraltet und der Schwerpunkt wird auf .Net gelegt.

Meine Anwendung enthält diese Dateien in der uses-Klausel: CRRDC, CRAXDRT_TLB,

Es funktioniert gut. Der Nachteil ist die Parameterübergabe. Meiner Meinung nach sind die Parameterdialogfelder, die mit dem Viewer geliefert werden, schrecklich. Daher verwende ich meine eigene Delphi-Anwendung, um Parameter abzufragen und sie an den Bericht zu übergeben.

0voto

bcorll Punkte 33

Hier ist eine etwas einfachere und saubere Klasse, die das Problem sehr gut löst:

Einheit CrystalReports; verwendet 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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X