Rave Report Tutorial - John COLIBRI. |
- résumé : Comment utiliser Rave Reports pour construire des états: données provenant d'une table, maître détail, titres et sous-totaux, réutilisation de parties, impression par programmation Delphi
- mots clé : Rave Report - génération d'état - fichiers .PDF, .HTML - tRvProject - Rave Designer
- logiciel utilisé : Windows XP personnel, Delphi 2006 - Rave Reports 6.5 BE (== Borland Edition)
- matériel utilisé : Pentium 2.800 Mhz, 512 Meg de mémoire, 250 Giga disque dur
- champ d'application : Delphi 7, Delphi 8, Delphi 2005, Delphi 2006, Delphi 2007, Win32 ou .Net
- niveau : développeur Delphi Windows
- plan :
1 - Reporting en Delphi
Jusqu'à Delphi 6, le générateur d'état installé avec Delphi était Quick Report. Après Delphi 6, Borland (Devco, CodeGear) a proposé plusieurs
générateurs d'états, et pour les versions Win32, essentiellement Rave Reports (pour la version .Net, Crystal Report semble privilégié, mais Rave
Reports a aussi sorti une version pour .Net, mais qui ne sera pas présentée ici). Notre but est de présenter ici comment utiliser Rave Reports pour réaliser ses premiers états.
Rave Reports est essentiellement un générateur "à bandes", comme Quick Report l'était. Mais une séparation soigneuse des fonctionalités permet d'utiliser Rave Reports
2 - Imprimer la Table d'une base avec Rave Reports 2.1 - Générateurs par Code et Générateurs par Bande Il existe en gros deux grandes familles de générateurs d'état:
- les générateurs à code, où le développeur utilise dans des procédures Delphi des appels à des librairies pour afficher des titres, des colonnes, effectuer des sous-totaux etc
- les générateurs à bande, où le développeur place sur une surface de conception des "bandes" qui représentent la ligne courante du futur état. La
librairie de reporting utilise alors ce modèle pour formater les données à imprimer
Quick Report était nettement un outil à bande.
Rave Reports en revanche est un outil hybride: - nous pouvons créer des états uniquement par code
- nous pouvons aussi utiliser des états à partir de modèles à bandes
Nous allons tout d'abord présenter comment utiliser Rave Reports pour imprimer le contenu d'une Table provenant d'une base de données, puis nous examinerons les autres possiblités offerte par Rave Reports
2.2 - Comment imprimer la Tables d'une Base Pour réaliser un état Rave Reports nous pouvons utiliser les étapes suivants: - nous créons un projet Delphi, et armons une Table sur la Forme (le moteur
peut être dBase, Paradox, Access, Interbase, SqlServer etc. Les composants d'accès le BDE, dbExpress, Interbase Express etc)
- nous utilisons un composant tRvProject. Celui ci
- permet de lancer le Designer Rave, qui est un .EXE indépendant permettant de spécifier le contenu de notre état.
- contient une méthode tRvProject.Execute qui imprime notre état
Le Designer Rave est une application très semblable à Delphi, avec une Palette, un Inspecteur, une surface de dessin. Nous pouvons aussi prévisualiser cet état. Puis nous devons sauvegarder les paramètres de cet état
dans un fichier .RAV qui sera réutilisé par Delphi pour imprimer l'état. Un fichier .RAV, est une sorte de .DFM (un codage binaire sur disque des paramètres de l'état). En réalité, le Designer est un outil annexe pour créer
le fichier .RAV qui est utilisé pour lancer une impression depuis Delphi.
Schématiquement, ceci peut se représenter par les schémas suivants: - une appplication Delphi importe les données d'une base de données
- Rave Designer est lancé en étant lié à Delphi:
- le développeur utilise Rave Designer pour construire l'état. prévisualise éventuellement l'état, puis sauvegarde le résultat dans le fichier .RAV :
- Delphi exécute l'état ainsi défini
Les étapes sont donc les suivantes
- créer un projet Delphi qui charge une Table d'une base de données
- lancer depuis Delphi le Rave Designer
- relier Delphi et le Rave Designer
- construire le rapport avec Rave Designer. Celui ci contiendra nos fameuses bandes
- éventuellement pré-visualiser le résultat
- sauvegarder les fichier
- lancer l'impression de cet état depuis Delphi
2.3 - Charger une Table BDE dans un projet Delphi Nous allons imprimer le contenu de CUSTOMER.DB, qui est une Table Paradox fournie dans la base DBDEMOS avec Delphi Les étapes sont les suivantes:
| lancez Delphi 2006 (multi-personnalité, ou version Win32) | |
créez un nouveau projet par "File | New | Vcl Forms Application - Win32" et sauvegardez le projet sous p_01_rave_db_bde | |
initialisez les composants pour accéder à CUSTOMER.DB - dans la Tools Palette, sélectionnez BDE, puis tTable, et posez-la sur la Forme
- dans l'Inspecteur d'Objet initialisez les propriétés suivantes:
- DataBase à DBDEMOS
- TableName à CUSTOMER.DB
- Active à True
- dans la Palette, de la page "Data Access", sélectionnez tDataSource, et dans l'Inspecteur, initialisez DataSet à Table1
- dans la Palette, de la page "Data Controls", sélectionnez dbGrid, et
dans l'Inspecteur, initialisez DataSource à DataSource1
| | le contenu de CUSTOMER est affiché dans la dbGrid |
Notez que - l'affichage dans la dbGrid est uniquement pour vérifier que nous avons bien accès aux données d'une Table. En fait, seul Table1 est nécessaire.
2.4 - Ajouter un Projet Rave Reports à notre projet Delphi A présent, préparons l'état: |
dans la Palette, sélectionnez l'onglet "Rave", sélectionnez le composant tRvProject: et posez-le sur la Forme |
| de la Palette, sélectionnez tRvDataSetConnection:
et posez-le sur la Forme. Dans l'Inspecteur, initialisez sa propriété DataSet à Table1 |
2.5 - Créer l'état avec Rave Designer
2.5.1 - Lancer Rave Designer depuis Delphi Pour lancer Rave Designer, il faut | cliquer deux fois sur RvProject1
| | Rave Designer est lancé
Vous distinguerez sans difficulté (image rétrécie pour éviter le défilement): - en haut un menu
- en dessous une Toolbar et une Palette
- à gauche un Inspecteur. Les propriétés affichées sont celles de
l'object courant sélectionné (coche verte) dans le TreeView de droite
- au centre la zone de dessin
|
Par défaut, le TreeView de droite contient un rapport Report1 (actuellement
sélectionné par la coche verte), avec une page Page1. Si quelqu'un a utilisé le Designer auparavant, il est possible que ce TreeView contienne les informations d'un projet précédent. Dans ce cas, selectionnez "File | New", et
vous retrouverez un nouveau projet vide, avec un premier rapport Report1 et une première page Page1. Ces noms, Report1 et Page1, peuvent, bien sûr être modifiés en utilisant l'Inspecteur.
2.5.2 - Relier Rave Designer et notre Table Delphi Une fois le Rave Designer ouvert avec un nouveau projet, il faut ajouter un
composant DataView, qui assurera le transfert des données depuis Delphi vers RaveReport. Pour cela: |
créez un nouveau DataView en sélectionnant "File | New Data Object" ou en cliquant directement l'icône de la Toolbar:
| | Rave Designer présente le dialogue de sélection de connections:
| | sélectionnez "Direct Data View" et cliquez "Next" |
| Rave Designer présente tous les composants tRvDatasetConnection composants actuellement présents sur la Forme Delphi.
Dans notre cas il n'y en a qu'un | | sélectionnez RvDatasetConnection1 et cliquez "Finish" |
| Rave Designer ajoute un DataView dans le "Data View Dictionary" de droite. | |
pour visualiser le contenu du DataView, cliquez "Data View Dictionary", puis "DataView1" | |
tous les champs de notre table sont présentés dans le TreeView de droite: Notez aussi que l'Inspecteur présente les propriétés de DataView1
|
2.5.3 - Création du Rapport Report1 Nous pouvons maintenant construire notre état. Comme indiqué plus haut, il va falloir placer une bande qui représente la ligne
courante de notre état. Rave Designer exige que ces bandes soient placées dans un conteneur appelé Region. C'est la Region qui définit le nombre de répétition d'une ligne: il est calculé en divisant la hauteur de la région par
la hauteur de la bande. Par conséquent: Par conséquent: | dans le TreeView, sélectionnez Page1 |
| dans la Palette, sélectionnez l'onglet "Report", et sur cet onglet, le composant Region:
et posez le sur la surface, pour qu'il occupe environ 80% de la surface | | la région est affichée en gris sombre (rétréci):
| | dans la Palette, sélectionnez une DataBand
et posez-la sur la Region1 | |
la bande se place au sommet de la région: | | dans l'Inspecteur, sélectionnez DataView et affectez-lui la valeur DataView1 |
| sélectionnez DataView1 dans le TreeView de droite, puis en appuyant Contrôle et en tirant-glissant, déplacez quelques champs de DataView sur
la DataBand | | pour faire joli ajoutez un titre en haut de la page: de l'onglet "Standard" de la Palette, sélectionnez un Text
et posez-le au sommet de la page | |
voici l'allure de notre page, avec le TreeView montrant la structure actuelle de notre page: |
Notez que
- les icônes de tous les éléments Rave Reports liés à des données (Region, DataText, CalcText que nous examinerons plus tard) se distinguent par un discret point rouge sombre en haut à droite:
2.5.4 - Prévisualisation depuis Rave Designer Nous pouvons déjà visualiser le résultat de cet état:
| sélectionnez le menu "File | Execute Report", ou cliquez l'icône de la Toolbar correspondante:
| | le dialogue de sélection de sortie est affiché: |
| sélectionnez "Preview" et cliquez "Ok" | | la page est pré visualisée:
|
Notez que - nous avons choisi de prévisualiser. Nous aurions aussi pu imprimer le rapport, ou créer différents types de fichiers
- .PDF, .HTML, .RTF, .TXT
- .PRN qui est un fichier imprimante
- .NDR qui est un fichier de résulat d'impression Rave Reports
Nous pourrions donc utiliser Rave Designer pour générer des documents
Acrobat, rédiger des courriers Word, et construire des pages Web !
2.5.5 - Sauvegarde du projet Rave Reports dans un fichier .RAV
Finalement il FAUT sauvegarder les paramètres de notre état dans un fichier .RAV: | selectionnez "File | Save As" et sauvegardez le fichier dans le répertoire
du projet Delphi, sous le nom de "rave_first_project" | | le fichier est sauvegardé sous RAVE_FIRST_PROJECT.RAV | Notez que
- comme Rave Designer est une application séparée de Delphi, elle gère son historique séparément. "Save As" peut très bien présenter par défaut un autre répertoire que le répertoire sous lequel vous avez sauvegardé le .DPR.
Vous pouvez sauvegarder le .RAV n'importe où, mais il faudra pouvoir le retrouver depuis Delphi, ce que nous allons examiner à présent
2.6 - Impression depuis Delphi
Pour prévisualiser un état, nous utilisons tRvProject.Execute: RvProject1.Open;
RvProject1.SelectReport('Report1', False); RvProject1.Execute;
RvProject1.Close; | où "Report1" est le nom du rapport dans Rave Designer que nous souhaitons
imprimer. Lorsqu'il n'y a qu'un seul rapport dans le projet (ce qui est notre cas), l'appel de SelectReport est optionnel. Par conséquent:
Notez que
- comme Rave a du parcourir toute la Table pour construire le résultat, notre dbGrid est bloqué en fin de Table. D'ailleurs nous ne pouvons pas quitter la prévisualisation sans fermer cette fenêtre (ShowModal de toute
évidence). Lorsque nous fermons la pré-visualisation, la dbGrid se repositionne au bon endroit.
2.7 - Les possibilités Rave Reports
Maintenant que nous avons vu comment réaliser notre premier état, nous pouvons mettre Rave Reports en perspective. - l'essentiel, à nos yeux, est tout d'abord de bien maîtriser la création de
rapports contenant des Tables avec Rave Designer: calculs de totaux, titres de colonnes, chaînage des pages etc
- Rave Report peut être utilisé de façon indépendante et le résultat lancé depuis Delphi
- nous pouvons aussi créer des impressions par code uniquement, sans utiliser Rave Designer
- finalement nous pouvons utiliser des scripts Rave Reports
Ces possibilités peuvent être résumées par le schéma suivant
3 - Création d'états Rave Report
3.1 - Un Etat d'une Table Interbase Nous pouvons utiliser d'autres moteurs Sql que Paradox, et d'autres composants d'accès que le BDE. Pour imprimer, depuis Delphi, il suffit simplement de
charger un tDataSet avec les données désirées. Montrons, pour la forme, comment imprimer une Table Interbase (en accéléré !) |
créez un nouveau projet Delphi 2006 Win32, et nommez-le p_02_db_ibx | |
posez un IbDataBase, cliquez deux fois sur IbDatabase1 et initialisez la base (EMPLOYEE.GDB dans notre cas), USER (SYSDBA) et PASSWORD (masterkey) | |
posez un tIbTransaction et liez-la à IbDatabase1 | |
posez un IbQuery, initialisez Database et initialisez Sql avec la table DEPARTMENT, basculez Active à True | |
à titre de vérification posez une DataSource et une dbGrid, connectez le tout | |
posez un tRvProject, une tRvDataSetConnection comme présenté ci-dessus, ouvrez Rave Designer, créez un nouveau Report et construisez l'état |
| posez un tButton pour lancer l'impression, initialisez RvReportFileName | |
compilez et exécutez | | voici le résultat: |
Nous utiliserons le BDE pour nos exemples ci-dessous, mais vous pouvez naturellement choisir une autre base / un autre jeu de composants d'accès.
3.2 - Paramètres Globaux
Par défaut, notre version de Rave Designer utilise des inch. Pour passer en centimètres, il faut changer les paramètres, et ceci doit être effectué avant de créer un état ou un page.
Nous démarrons d'abord un nouveau projet avec un Table CUSTOMER comme indiqué dans notre premier exemple: |
créez un nouveau projet Delphi 2006 Win32, et nommez-le p_03_rave_subtotal | |
posez une tTable, initialisez Database avec DBDEMOS, TableName avec CUSTOMER.DB et basculez Active à True | |
à titre de vérification posez une DataSource et une dbGrid, connectez le tout | |
posez un tRvProject, une tRvDataSetConnection comme présenté ci-dessus, ouvrez Rave Designer, créez un nouveau Report |
Puis, une fois dans Rave Designer
| sélectionnez "Edit | Preferences | Defaults" | |
la page des paramètres par défaut est affichée | | changez "Units" en cm, et "Draw Grid Every" en 10, et cliquez "Ok" |
| créez un nouveau projet Rave Reports, en sélectionnant "File | New" | |
un nouveau projet Rave Reports est affiché avec une grille en cm (21,0 cm de large) |
Notez que - les nouveaux paramètres sont aussi présentés dans les propriétés de l'élément RaveProject
3.3 - Fond de Page - Héritage de page Nous pouvons placer dans des "Pages Globales" des parties qui peuvent être réutilisées par n'importe quelle page de n'importe quel état (de ce projet
Rave Reports). Pour cela, il faut: - créer une page globale et la garnir avec les éléments qui seront incorporés à nos autres états
- lorsque nous souhaiterons récupérer ces éléments dans une page, ajouter
cette page globale comme "page miroir"
Voici un exemple: | sélectionnez "File | New Global Page", ou cliquez l'icône de la Toolbar:
| |
une page globale est ajoutée (elle figure dans le TreeView à droite, et devient la seconde page du NoteBook central). Cette page ressemble en tout point à une page normale |
| de l'onglet "Standard" de la Palette, sélectionnez une Section:
et placez la en haut de la page globale | | sélectionnez une Bitmap:
et placez la sur Section1. Initialisez sa propriété FileLink avec le chemin et le nom d'un fichier .BMP | | l'image est affichée |
| sélectionnez un élément "Text" et placez un titre sur la section, initialisez sa propriété Text avec un titre |
| voici notre page globale avec sa section: |
Voici comment incorporer cette section dans une page d'un quelconque Report: |
sélectionnez Page1 (par l'onglet du NoteBook central ou par le TreeView de droite) | |
sélectionnez une Section et placez-la où vous voulez voir apparaître l'image et le titre. En haut dans notre cas. | |
les éléments de la section globale sont affichés | | à titre d'exercice ajoutez un Text sur la Section copiée |
| voici le résultat: |
Notez que
- les Sections jouent le même rôle que les tPanels Delphi
- pour les miroirs
- le point haut à gauche définit la position de la copie, mais la largeur
et hauteur initiales sont définis par l'original. Ces propriétés de position ed de taille peuvent être ensuite modifiées, mais pas les éléments de la section originale (l'image et le titre).
- toute modification de la section originale est répercutée à tous ses miroirs
- nous pouvons ajouter de nouveaux éléments à la section miroir
- une Section d'une Page d'un Report peut être utilisée comme la source
pour un miroir d'une autre Page de ce même Report.
Ainsi la notion de "page globale" sert, comme en Pascal, à regrouper les sections communes à tous les Reports d'une même Project.
En revanche, n'importe quelle Section peut être utilisée comme source et être copiée (mirror) dans la section d'une autre Page: nous pouvons utiliser les Sections d'une quelconque page du même Report ou celles
d'une quelconque page globale. En fait la propriété Mirror nous présente ce qui est disponible
3.4 - Variables de Report et Expressions
Nous pouvons ajouter des éléments tels que la date, le numéro de page etc. Cela se fait par le biais d'élément DataText dont nous spécifions le contenu à l'aide d'un Editeur spécialisé.
Voici comment ajouter le numéro de page à Page1: | sélectionnez Page1 |
| de l'onglet "Report" de la Palette, sélectionnez un DataText:
et posez le sur Page1 (dans la section du titre par exemple, ou ailleurs) | |
dans l'Inspecteur, sélectionnez DataField et cliquez l'ellipse ... | |
l'Editeur de Données est affiché (sans les marques de couleur): |
L'Editeur fonctionne ainsi:
| vous sélectionnez ou tapez une valeur dans les combo marquées d'une croix rouge | |
vous cliquez l'un des boutons dans le rectangle jaune | | le texte correspondant est affiché dans le tMemo du bas (points
d'exclamation verts) ou vous pouvez modifier le texte à votre guise |
Pour avoir la date, il faut utiliser la variable Report.CurrentPage. Donc:
3.5 - Bande Titre de Colonne 3.5.1 - Les Bandes de titre et de totaux
Les titres de colonnes et les sous totaux divers sont des éléments Band (pas DATAband, mais BAND). Ils sont aussi placés sur une Region, et encadrent
en général des DataBand qui contiennent les données des lignes d'une Table. De plus ces lignes devront contenir une référence de la bande détail qu'ils encadrent.
C'est un peu similaire à un code Pascal utilisé pour calculer un total: - nous initialisons le total
- une boucle effectue les calcul
- nous affichons le résultat
xxx
my_total:= 0;
FOR my_index:= 0 TO 10 DO BEGIN
Inc(my_total, ...ooo...); END; // for
Caption:= IntToStr(my_total); |
Au niveau Rave Reports, nous encadrons de même la ligne courante par une bande de titre (initialisation) et une bande qui affiche des sous-totaux (affichage du résultat). Mais au lieu de décaler les calculs vers la droite,
Rave Reports considère que la bande détail est "au-dessus" du niveau qui contient les bandes titres et sous-totaux:
Les titres peuvent être disposés à plusieurs endroits: - uniquement au début de la première ligne de données
- au début des lignes de chaque nouvelle page
- à la fois au début de la première ligne ET des premières lignes de chaque page etc
Cette position est spécifiée par la propriété Band.BandStyle.
3.5.2 - Ajout d'une bande de données détail
D'abord, ajoutons notre Table: | dans Rave Designer, sélectionnez "File | New Data Object | Direct Data
View" et cliquez "Next" et sélectionnez RvDatasetConnection1 | | de l'onglet "Report" de la Palette, sélectionnez Region et placez-la sous
le titre | | sélectionnez DataBand, posez-la sur Region1, et initialisez DataView à DataView1 |
| dans le TreeView, sélectionnez "Data View Dictionary | DataView1", puis avec Contrôle-Click gauche souris, tirez et glissez quelques champs sur DataBand1 |
| sélectionnez "File | Execute Report" pour vérifier le résultat |
3.5.3 - Ajout de la Bande de titre Ajoutons un titre:
| sélectionnez l'onglet "Report", puis l'élément Band
et placez-la sur la Region | | la bande est placée APRES la bande donnée |
| sélectionnez l'onglet "Alignment" de la Palette et l'icône "Move Behind" |
| Band1 est placé au sommet de Region1, et "en dessous" | |
dans l'Inspecteur, sélectionnez ControllerBand et affectez lui la valeur DataBand1 | |
le symbole de Band1 devient une flèche vers le bas | | sélectionnez BandStyle pour préciser où les titres devront être affichés |
| un éditeur de bande est présenté: Dans cet éditeur:
- la bande qui a été utilisée pour ouvrir l'éditeur est soulignée (Band1 ici)
- les symboles (triangle ou losange) sont reproduits
- les DataBand sont présentés 3 fois pour "représenter la répétition".
Nous n'avons qu'une seule DataBand, mais cette répétition préfigure, avec un peu d'imagination, la répétition des lignes de la Table
- normalement "Body Header" et "First" sont cochés
|
| coches "Body Header", "First" et "New Page" et cliquez "Ok" | |
placez quelques titres sur Band1: - de l'onglet "Standard", sélectionnez Text, posez-le sur Band1, et initialisez sa propriété Text, par exemple "Numéro"
- ajoutez de même d'autres titres de colonne
| | ajoutez aussi une trait horizontal pour séparer le titre - de l'onglet "Drawing" sélectionnez la ligne horizontale, et placez la sous les titres
| | voici notre maquette: |
Sauvegardez l'état
| sélectionnez "Save As" et tapez le nom, par exemple "rave_sub_total_project" |
Retournez sur la Forme Delphi et lancez l'état
3.5.4 - Ajout d'une bande de sous-totaux Calculons, par exemple, le nombre de lignes de notre état. Pour cela, nous allons - ajouter une Band, et spécifier qu'elle est une bande de pied de lignes (Footer band)
- placer sur cette Band un CalcText et initialiser ses liens avec la DataBand ainsi que l'expression de calcul
Donc: |
de l'onglet "Report", sélectionnez une Band et placez-la sur la Forme. | | son icône est un losange rouge |
| Dans ControllerBand, sélectionnez DataBand1 | |
son icône devient un triange pointant vers le haut (Band1, DataBand1 et Band2 font partie de la même boucle) Sélectionnez BandStyle, et dans l'Editeur, sélectionnez "Body Footer" |
| sélectionnez CalcText: et posez le sur Band2. Puis, dans l'Inspecteur
- sélectionnez la propriété Controller, et initialisez la à DataBand1
- sélectionnez CalcType et initialisez-la à ctCount
- sélectionnez DataField, et dans l'Editeur, dans "Data Field",
sélectionnez "CustNo" et cliquez "Insert Field". L'expression devient:
DataView1.CustNo | |
pour la forme, ajoutez une ligne de séparation horizontale, et un Text "Nombre de clients :" | | voici notre maquette:
| | sélectionnez "File | Execute Report" |
| voici le résultat (dernière page): |
| sauvegardez le projet Rave Reports |
Notez que: - sur chaque bande se trouve un résumé de l'emplacement (header, footer ...)
et de l'occurence (First, New Page ...). L'explication des lettres (B, b etc) se trouve dans le dialogue BandStyle
- nous ne détaillerons pas toutes les opérations possibles (somme, moyenne, ...)
- d'autres opérations sont possibles en utilisant les éléments CalcOp ou CalcTotal
3.6 - Relation Maître Détail
Nous allons à présent imbriquer des bandes pour présenter les factures de chaque client.
Commençons par ajouter notre seconde Table: |
sélectionnez le projet Delphi | | ajoutez une nouvelle tTable (DBDEMOS, "ORDERS.DB", True) |
| ajoutez une RvDataSetConnection (Dataset= Table2), éventuellement une DataSource / dbGrid pour vérification |
| compilez et exécutez pour vérifier le tout |
Importons la Table "ORDERS.DB" dans Rave Designer:
| sélectionnez Rave Designer | |
sélectionnez "File | New Data Object | Direct Data View | Next | RvDataSetConnection2 | Finish" | |
les champs de la table ORDERS sont affiché dans le TreeView sous "Data View Dictionary | DataView2" |
Préparons maintenant une nouvelle page:
| sélectionnez "File | New Report Page" | |
Page2 est ajoutée au projet (nouvel onglet central, nouvel élément dans le TreeView de droite) | | ajoutez un titre à cette page:
- posez un Section en haut de la page
- dans sa propriété Mirror, sélectionnez Page1.Section1 (un miroir d'une section d'une autre page)
|
| pour distinguer visuellement cette page de la Page1, placez sous le titre un Rectangle, avec une bordure de couleur |
Pour que l'exécution affiche notre nouvelle Page2 (et non pas Page1), il faut: - soit chaîner Page1 à Page2, en initialisant Page1.GotoPage à Page2
- soit, pour nos essais, spécifier que seule Page2 doit être imprimée.
Pour cela:
Et plaçons nos bandes: |
posez une Region qui occupe la place sous le titre | | sur la Region, posez - une Band pour le titre
- deux DataBand (pour le maître et le détail)
- une Band pour les totaux
| | initialisez les positions et occurences des bandes:
- sélectionnez Band1, et
- dans ControllerBand, sélectionnez "DataBand1"
- dans BandStyle, sélectionnez "Body Header", "First", "New Page"
- sélectionnez DataBand1 et
- dans BandStyle, sélectionnez "Body Header"
- sélectionnez DataBand2 et
- dans ControllerBand, sélectionnez "DataBand1"
- dans BandStyle, sélectionnez "Detail"
- sélectionnez Band2, et
- dans ControllerBand, sélectionnez "DataBand1"
- dans BandStyle, sélectionnez "Footer"
|
| l'éditeur de style "représente" le type de répétition de notre état: Notez que les codes de couleur sont là uniquement pour représenter
l'emboîtement des répétitions (et non pas, comme nous le croyions au début pour représenter un état "bien initialisé" et "non initialisé correctement) | |
initialisez les liaisons aux données: - sélectionnez DataBand1, et initialisez DataView avec DataView1
- sélectionnez DataBand2, et initialisez DataView avec DataView2
|
| initialisez la relation maître détail: - sélectionnez DataBand2
- initialisez MasterDataView à DataView1
- sélectionnez MasterKey. L'Editeur "Data Text Editor" est affiché, et dans "Data Field", sélectionnez "CustNo" et cliquez "Insert Field"
- sélectionnez DetailKey" et dans l'Editeur, sélectionnez "Custno",
cliquez "Insert Field"
| | voici la vue de l'Inspecteur: |
Notez que - l'Inspecteur affiche en gras les propriétés que nous avons modifiées, ce qui est très pratique
- MasterKey et DetailKey sont toutes deux égales à CustNo, parce qu'il se
trouve que les Tables ont les mêmes noms de champs: CUSTOMER.CUSTNO et ORDERS.CUSTNO. Et dans Rave Designer, il s'agit donc de DataView1.CustNo
et DataView2.Custno, les DataView utilisées étant affichées dans l'Editeur de données
Finalement, peuplez les bandes |
sur Band1, placez, par exemple, les Text "Numéro" et "Société" et une ligne horizontale | |
sur DataBand1, CustNo et Company, tirés de DataView1 | |
sur DataBand2, OrderNo, Custno, AmountPaid, tirés de DataView2, et AmountPaid aligné par FontJustify à droite | |
sur Data2, un CalcText (Controller= DataBand2, DataField= DataView2.AmountPaid) avec un titre et une ligne horizontale |
| voici notre maquette: |
| sélectionnez "File | Execute Report" | | voici la première page:
|
3.7 - Chaînage de pages Notre Report1 comporte donc deux pages. Pour notre exemple précédent, nous
avons forcé Page2 à être la seule page affichée. Nous pouvons à présent réintégrer Page1, en utilisant Report1.PageList et en ajoutant Page1
3.8 - Sélection d'états
Si notre RaveProject comporte plusieurs états, nous pouvons les sélectionner dans notre application Delphi par RvProject.SelectReport. Ajoutons par exemple un autre état
| sélectionnez "File | New Report" | | Report2 est ajouté au TreeView |
| placez quelques éléments sur Report2.Page1, par exemple un Text "Rapport 2" |
| sauvegardez par "File | Save" |
Pour sélectionner l'état qui sera affiché par notre projet Delphi, nous
utilisons tRvProject.SelectReport. Nous pouvons un peu automatiser le choix en utilisant une tListBox pour sélectionner le rapport:
Notez que
- normalement nous donnons des Name significatifs à tous les éléments de RaveReport. Au lieu de Report2, nous pourrions nommer l'état "Stocks 2007". C'est ce Report.Name qui doit être utilisé dans
tRvProject.SelectReport
- la structure d'un RaveProject (le contenu du .RAV) peut donc être schématisée par:
4 - Rave Designer autonome 4.1 - Affichage de Tables dans Rave Designer Nous pouvons aussi importer les données directement dans Rave Designer (sans
placer de DataSet sur une application Delphi). Démarrons donc Rave Designer indépendemment de Delphi:
Importons des donnée de la table DBDEMOS.CLIENTS.DBF:
Nous ajoutons une DataView correspondant à une Table de la base: | sélectionnez "File | New Data Object | Driver Data View" |
| un dialogue nous demande de préciser la base de donnée: |
| cliquez "Finish" | |
un Editeur de Requêtes est présenté, avec les Tables disponibles: | |
sélectionnez à droite "CLIENTS.DBF" et tirez-la sur la surface à gauche: | | un diagramme représentant la Table et ses champs est affichée.
Au lieu de * nous pouvons cocher tel ou tel champ. Le résultat va générer une requête |
| affichez la requête SQL en cliquant le bouton "Editor" | | le texte de cette requête est affiché:
| | modifiez éventuellement la requête et cliquez "Ok" |
| dans le TreeView, "Data View Dictionary" comporte une nouvelle entrée "DriverDataView1" avec tous les champs de notre Table |
A partir de là vous savez déjà faire:
4.2 - Affichage d'un état autonome dans Delphi Bien que nous ayons créé l'état sans Delphi, nous pouvons néanmoins lancer l'impression depuis un projet Delphi. Il suffit de spécifier le nom du .RAV,
ET d'importer la .DLL qui sait exécuter ces états autonomes. Dans notre cas, il s'agit de RvDlBDE
Par conséquent
Notez que - si vous utilisez une autre base que le BDE, le nom de l'UNITé d'importation sera différent du nôtre. Ce n'est pas grave: en exécutant, un dialogue d'erreur vous présentera exactement le nom que vous devez taper. Si
votre répertoire "Program Files.Borland.BDS4" ne contient pas ce .DCU, voyez le site de Nevrona
- si vous rencontrez une erreur du style "unable to gain control of Rave
Reports", fermez toute exécution de Rave Reports et recommencez
5 - Création d'états par Code 5.1 - Impression par Programmation Delphi
Nous nous sommes surtout penchés sur l'impression de tables provenant de bases de données. Mais nous pouvons aussi imprimer des données uniquement par des appels depuis un projet Delphi de primitives Rave Reports. Pour cela
- nous utilisons le composant tRvSystem
- nous plaçons dans tRvSystem.OnPrint des instructions similaires à celles utilisées par tCanvas: GoToXY, SetFont, Print NewLine etc
- nous lançons l'impression par tRvSystem.Execute
Impression d'un texte Voici un exemple qui va imprimer un simple texte: |
lancez Delphi 2006 | | créez un nouveau projet Win32, et nommez-le p_05_rave_code_report |
| de l'onglet "Rave" de la Tools Palette, sélectionnez un tRvSystem |
| créez l'événement RvSystem1.OnPrint, et tapez le code suivant:
procedure TForm1.RvSystem1Print(Sender: TObject);
begin
with Sender as TBaseReport do
begin SetFont('Arial', 18);
GotoXY(1,1); Print('Rave Code Based Reporting');
end; // with Sender as TBaseReport
end; // RvSystem1Print | | |
posez un tButton, nommez-le "preview_" et, dans son OnClick, lancez l'impression:
procedure TForm1.RvSystem1Print(Sender: TObject);
begin
with Sender as TBaseReport do
begin SetFont('Arial', 18);
GotoXY(1,1); Print('Rave Code Based Reporting');
end; // with Sender as TBaseReport
end; // RvSystem1Print | | |
compilez, exécutez, cliquez "preview_" | | voici le résultat: |
5.2 - Une tableau tabulé Terminons par un exemple un peu plus significatif. Nous allons imprimer un tableau en présentant les données en colonnes. Pour cela
- nous initialisons les taquets de tabulation par ClearTabs et SetTab
- nous imprimons chaque ligne en appelant PrintTab autant qu'il y a de taquets
Voici un exemple simple
| ajoutez une méthode qui initialise les taquets et imprime quelques lignes. Nous avons choisi d'imprimer chaque ligne dans une procédure emboîtée print_training:
procedure print_tabulated_report(p_c_base_report: TBaseReport);
procedure print_training(p_training_name: String;
p_day_count: Integer; p_price: Double);
begin
with Form1, p_c_base_report do
begin PrintTab(p_training_name);
PrintTab(IntToStr(p_day_count));
PrintTab(Format('%m', [p_price]));
NewLine; end; // with p_c_base_report do
end; // print_training begin // print_tabulated_report
with Form1, p_c_base_report do
begin // -- page header
SetFont('Arial', 18); GotoXY(1,1);
Print('Formations Delphi'); NewLine; NewLine;
// -- set the tabs ClearTabs;
SetTab(0.2, pjLeft, 1.7, 0, 0, 0);
SetTab(1.0, pjRight, 1.5, 0, 0, 0);
SetTab(1.9, pjRight, 1.7, 0, 0, 0);
// -- column title SetFont('Arial', 10);
Bold := True; PrintTab('Formation');
PrintTab('Jours'); PrintTab('Prix');
NewLine; // -- the details
Bold := False; NewLine;
// -- print each tabulated line
print_training('Formation Rave Report', 3, 1400);
print_training('Formation Delphi Complète', 5, 2400);
print_training('Formation IntraWeb', 3, 1400);
print_training('Formation Interbase C/S', 3, 1400);
end; // with p_c_base_report do
end; // print_tabulated_report | | |
comme toutes les impression sont effectuées dans le callback RvSystem1.OnPrint (appelée après le dialogue de choix de sortie), il faut ventiler les différents types d'états à imprimer. Nous avons choisi
d'utiliser une variable globale, initialisée dans chaque bouton d'impression. Voici le code:
var g_report_kind: Integer= 0;
procedure TForm1.RvSystem1Print(Sender: TObject);
begin case g_report_kind of
1 : print_title(Sender as TBaseReport);
2 : print_tabulated_report(Sender as TBaseReport);
end; // RvSystem1Print end; // RvSystem1Print
procedure TForm1.preview_Click(Sender: TObject);
begin g_report_kind:= 1; RvSystem1.Execute;
end; // preview_Click
procedure TForm1.preview_trainings_Click(Sender: TObject);
begin g_report_kind:= 2; RvSystem1.Execute;
end; // preview_trainings_Click | | |
compilez, exécutez, cliquez "preview_trainings_" | | voici le résultat:
|
6 - Remarques sur Rave Reports Quelques commentaires - Rave Reports est globalement très satisfaisant. La séparation de Rave
Designer et de l'IDE Delphi est une bonne option, et elle permet de fournir à nos utilisateurs un outil de reporting indépendant. Outil à double tranchant pour certains développeurs, qui préfèrent facturer chaque
modification plutôt que de laisser le client créer ses propres états, alors que d'autres ne sont que trop heureux de les laisser transpirer un peu avec leurs lubies de modifications permanentes. A vous de choisir ...
- l'aide de Rave Reports dans Delphi est assez, hmm, surprenante. Une liste de CLASSES (sans leurs attributs, méthodes, événements), une liste séparée
de toutes les PROPERTYes, une liste de méthode et une liste d'événements:
Et nous qui croyions que nous étions en programmation objet ?
D'ailleurs cette aide n'apparaît pas par appui de F1 sur un composant Rave Reports (il faut l'installer dans la mécanique d'aide, ou ouvrir l'aide et naviguer sur le sujet qui nous intéresse)
- nombreux sont les gourous qui terrorisent les personnes habituées à Quick Report en avertissant que "RAVE est totalement différent". Que nenni: c'est un générateur à bande, avec en plus, un designer autonome, et la possibilité
d'effectuer ses impressions par code.
Ce qui est difficile, en revanche, c'est de présenter simplement la construction du premier état, car il y a 9 parties séparées:
- Delphi (avec la Palette, l'Inspecteur d'Objet, la Forme et l'UNITé)
- Rave Designer (avec le Menu, le Treeview, l'Inspecteur, la Palette
et la surface de dessin)
Donc un peu plus délicat de présenter où cliquer pour obtenir ce que l'on souhaite. Mais çà c'est notre problème de présentateur, et si nous avons
correctement fait notre travail, vous ne devriez pas (trop) vous en rendre compte. - dans Rave Designer, le fait que certains éléments soient ajoutés via le
menu (les DataViews par exemple) et que d'autre le soient par la Palette (les Regions, les Bandes) peut aussi dérouter au départ. De plus le TreeView pourrait comporter un menu contextuel (click droit et "Add
Dataview" etc). Une critique mineure, en réalité
7 - Télécharger le code source Delphi Vous pouvez télécharger: Ce .ZIP qui comprend:
- le .DPR, la forme principale, les formes annexes eventuelles
- les fichiers de paramètres (le schéma et le batch de création)
- dans chaque .ZIP, toutes les librairies nécessaires à chaque projet (chaque .ZIP est autonaume)
Ces .ZIP, pour les projets en Delphi 6, contiennent des chemins RELATIFS. Par conséquent: - créez un répertoire n'importe où sur votre machine
- placez le .ZIP dans ce répertoire
- dézippez et les sous-répertoires nécessaires seront créés
- compilez et exécutez
Ces .ZIP ne modifient pas votre PC (pas de changement de la Base de Registre, de DLL ou autre). Pour supprimer le projet, effacez le répertoire.
La notation utilisée est la notation alsacienne qui consiste à préfixer les identificateurs par la zone de compilation: K_onstant, T_ype, G_lobal,
L_ocal, P_arametre, F_unction, C_lasse. Elle est présentée plus en détail dans l'article La
Notation Alsacienne
Comme d'habitude: - nous vous remercions de nous signaler toute erreur, inexactitude ou
problème de téléchargement en envoyant un e-mail à jcolibri@jcolibri.com. Les corrections qui en résulteront pourront aider les prochains lecteurs
- tous vos commentaires, remarques, questions, critiques, suggestion d'article, ou mentions d'autres sources sur le même sujet seront de même les bienvenus à jcolibri@jcolibri.com.
- plus simplement, vous pouvez taper (anonymement ou en fournissant votre e-mail pour une réponse) vos commentaires ci-dessus et nous les envoyer en cliquant "envoyer" :
- et si vous avez apprécié cet article, faites connaître notre site, ajoutez un lien dans vos listes de liens ou citez-nous dans vos
blogs ou réponses sur les messageries. C'est très simple: plus nous aurons de visiteurs et de références Google, plus nous écrirons d'articles.
8 - Références Quelques références:
- Nevrona est la société qui produit Rave Report. Vous y trouverez les mises à jour, les .DLL, les nouvelles versions
- Rave, .PDF, Intraweb : un article où nous présentons
- comment générer, depuis une applications Delphi, des états au format .PDF
- la lecture et la génération de fichiers .PDF depuis des pages Web créées avec Intraweb
- Vidéo Rave Report : le fichier .SWF (55
minutes) de la conférence CodeGear d'octobre 2008 (architecture, utilisation de section, titres et totaux / sous totaux, relations maître détail et création d'états)
Nous présentons aussi Rave Reports dans nos formations:
Et finalement, pour ceux qui souhaitent se concentrer sur Rave, nous proposons une
Nos exemples mentionnent Intraweb. Pour les personnes intéressées, nous avons rédigé un Tutorial Intraweb et présentons ce produit
Delphi dans nos formations abordant les techniques Internet / Web
9 - L'auteur John COLIBRI est passionné par le développement
Delphi et les applications de Bases de Données. Il a écrit de nombreux livres et articles, et partage son temps entre le développement de projets (nouveaux projets, maintenance, audit, migration BDE, migration Xe_n, refactoring) pour ses clients, le
conseil (composants, architecture, test) et la
formation. Son site contient des articles
avec code source, ainsi que le programme et le calendrier des stages de formation Delphi, base de données, programmation objet, Services Web, Tcp/Ip et
UML qu'il anime personellement tous les mois, à Paris, en province ou sur site client. |