FAQ DelphiConsultez toutes les FAQ

Nombre d'auteurs : 123, nombre de questions : 919, dernière mise à jour : 14 juin 2019  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).

Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.

L'équipe Delphi de Developpez.com.

Commentez


SommaireGénérateurs d'étatsCrystal Report (4)
précédent sommaire suivant
 

Crystal Report propose différents moteurs qui peuvent être utilisés depuis un outil de développement RAD :

  • Crystal Report Print Engine (API) crpe32.dll ;
  • Crystal ActiveX (OCX) control CRYSTL32.OCX ;
  • Report Designer Component (RDC) craxdrt.dll.

Le plus connu sous Delphi est Crystal Report Print Engine (API) car il existe un composant VCL qui permet de l'utiliser. Mais ce n'est certainement pas le plus intéressant. Un des meilleurs moteurs est le Report Designer Component (RDC), il a été spécialement écrit pour l'environnement VB et il permet d'interagir directement avec le rapport durant son impression pour pouvoir modifier le résultat. Il exploite pleinement les objets COM de Windows, ce qui va nous permettre de l'utiliser depuis Delphi.

Mis à jour le 19 octobre 2013 sur_uix

Le RDC est divisé en trois "grands" objets :

  • le viewer ;
  • le rapport ;
  • le container.

Le viewer se trouve dans une DLL : CrViewer.dll.
Le rapport et le container dans une autre DLL : craxdrt.dll.

Pour utiliser le RDC sous Delphi, il faut importer ces deux DLL (qui ne sont rien d'autre que des objets COM).

Pour ajouter le viewer : Composants -> Importer un contrôle ActiveX… et là vous prenez Crystal Report Viewer Control puis "Installer…", ce qui vous donnera un composant TCRViewer.

Pour ajouter le moteur : Projet -> Importer une bibliothèque de types… et là vous prenez Crystal Report ActiveX Designer Run Time Library, cochez la case « Générer le Wrapper de composant » puis « Installer… », ce qui vous donnera entre autre un TApplication et un TReport.

Je vous conseille de modifier le nom de toutes les classes ; par exemple, TApplication en TCRApplication. Sinon certaines classes du RDC seront en conflit avec d'autres déjà existantes dans Delphi.

Après cela, vous aurez entre autre deux nouveaux fichiers CRVIEWERLib_TLB.pas et CRAXDRT_TLB.pas.
Je vous conseille d'aller vous balader un peux dedans pour voir de quoi il en retourne vous constaterez que les créateurs de Crystal Report maîtrisent bien COM.

Mis à jour le 22 janvier 2014 sur_uix

Pour pouvoir faire un aperçu avec le RDC, il nous faut au minimum trois classes :

  • TCRviewer pour l'aperçu ;
  • TCRReport, qui contient le rapport ;
  • TCRApplication pour charger le rapport.

Créer un projet Delphi vide avec une feuille FORM1.
TCRViewer est un composant visuel, on peut alors le placer sur FORM1 comme n'importe quel autre composant Delphi (DragAndDrop).
On ajoute encore un bouton (Button1) avec une méthode sur l'événement onClick.

Maintenant voici comment on affiche un rapport :
  • on l'ouvre -> crReport := crApplication.OpenReport(FileName, crOpenReportByTempCopy); ;
  • on dit au viewer quel rapport il doit afficher -> crViewer91.ReportSource := crReport; ;
  • on affiche le rapport -> crViewer91.ViewReport;.

Mis à jour le 22 janvier 2014 sur_uix

D'après les créateurs de Crystal Reports, avec Visual Basic, il faut modifier la propriété FormattedPicture de l'objet OLE. La difficulté c'est que nous nous avons Delphi, il va falloir transcrire leur exemple VB en Delphi.

Analysons leur exemple :

  1. dans Crystal, placer un objet OLE, appelé Picture1, dans un section, appelé Section3 ;
  2. depuis VB, traper l'événement Format de la Section du rapport ;
  3. dans l'événement Format, modifier l'objet Picture avec l'image qui se trouve sur votre disque.

Par exemple :
Code vb : Sélectionner tout
1
2
3
Set Picture1.FormattedPicture = LoadPicture(Field3.Value) 
'Field3 pourrait être un FormulaField qui retourne 
"pic" + ToText({Hetype.Type,0}) + ".jpg"

Maintenant le plus compliqué c'est le point 2, car cela demande pas mal de notions COM en Delphi.
Dans le fichier CRAXDRT_TLB.pas, on a la section ISection et son événement ISectionEvent.
Il faut faire un wrapper pour ces deux interfaces.
Voici ce que je vous propose :

Pour l'en-tête :
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  TCrSectionFormat = procedure (Sender: TObject; const pFormattingInfo: IDispatch) of object; 
  
  TCrSection = class(TOleServer) 
  private 
    FOnFormat : TCrSectionFormat; 
    FIntf:        ISection; 
    function      GetDefaultInterface: ISection; 
  protected 
    procedure InitServerData; override; 
    procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override; 
  published 
    property OnFormat: TCrSectionFormat read FOnFormat write FOnFormat; 
  public 
    constructor Create(AOwner: TComponent); override; 
    destructor  Destroy; override; 
    procedure Connect; override; 
    procedure ConnectTo(svrIntf: ISection); 
    procedure Disconnect; override; 
    property  DefaultInterface: ISection read GetDefaultInterface; 
    property Intf:ISection read FIntf; 
  end;

Pour le corps :
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
{ TCrSection } 
  
procedure TCrSection.Connect; 
var 
  punk: IUnknown; 
begin 
  if FIntf = nil then 
  begin 
    punk := GetServer; 
    ConnectEvents(punk); 
    Fintf:= punk as ISection; 
  end; 
end; 
  
procedure TCrSection.ConnectTo(svrIntf: ISection); 
begin 
  Disconnect; 
  FIntf := svrIntf; 
  ConnectEvents(FIntf); 
end; 
  
constructor TCrSection.Create(AOwner: TComponent); 
begin 
  inherited Create(AOwner); 
end; 
  
destructor TCrSection.Destroy; 
begin 
  inherited Destroy; 
end; 
  
procedure TCrSection.Disconnect; 
begin 
  if Fintf <> nil then 
  begin 
    DisconnectEvents(FIntf); 
    FIntf := nil; 
  end; 
end; 
  
function TCrSection.GetDefaultInterface: ISection; 
begin 
  if FIntf = nil then 
    Connect; 
  Assert(FIntf <> nil, 'DefaultInterface is NULL. Component is not'+ 
      ' connected to Server. You must call ''Connect'''+ 
      ' or ''ConnectTo'' before this operation'); 
  Result := FIntf; 
end; 
  
procedure TCrSection.InitServerData; 
const 
  CServerData: TServerData = ( 
    ClassID:   '{AF3768D4-6120-4E28-96DD-63FD2DC27B7A}'; 
    IntfIID:   '{AF376806-6120-4E28-96DD-63FD2DC27B7A}'; 
    EventIID:  '{AF37684B-6120-4E28-96DD-63FD2DC27B7A}'; 
    LicenseKey: nil; 
    Version: 500); 
begin 
  ServerData := @CServerData; 
end; 
  
procedure TCrSection.InvokeEvent(DispID: TDispID; 
  var Params: TVariantArray); 
begin 
  case DispID of 
    -1: Exit;  { DISPID_UNKNOWN} 
  1: if Assigned(FOnFormat) then 
    FOnFormat(Self, Params[0]); 
  end; {case DispID} 
end;
Vous ajoutez cela dans le fichier CRAXDRT_TLB.pas.
Maintenant, vous avez une classe TCrSection qui se connecte sur n'importe quelle section du rapport et vous propose l'événement OnFormat(…).

Pour l'utiliser c'est simple :
Code delphi : Sélectionner tout
1
2
3
  FRptSection := TCRSection.Create(nil); 
  FRptSection.OnFormat := FormatOLE; 
  FRptSection.ConnectTo(crReport.Sections.Get_Item('DetailSection1'));
FormatOLE est votre procedure qui serra appelé par l'événement onFormat. C'est là-dedans que vous coderez le chargement de l'image.
Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var 
  strPath : string; 
  oPicture: TPicture; 
  pd: IPictureDisp; 
  oBitmap : TBitmap; 
{…} 
  oPicture := TPicture.Create; 
  try 
    oBitmap := LoadGraphicsFile(strPath); 
    oPicture.Bitmap := oBitmap ; 
    GetOLEPicture(oPicture, pd); 
    Picture1.FormattedPicture := pd; 
  finally 
    oPicture.Free; 
    oBitmap.Free;             
    oBitmap := nil;             
    pd := nil; 
  end;

Mis à jour le 22 janvier 2014 sur_uix

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2019 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -

Partenaire : Hébergement Web