Introduction▲
Crystal Reports est l'outil de création d'états fourni avec Visual Studio .NET. Dans cet article nous allons voir comment créer très simplement un état alimenté par des données extraites d'une application .NET et comment afficher l'état généré dans une fenêtre Windows. Nous finirons ce tutoriel par quelques explications sur le déploiement d'applications winforms utilisant des états Crystal Reports.
Prérequis :
- connaissances en ADO.NET : Les tutoriels et cours DotNET regardez les cours de la rubrique : « .NET et les bases de données » ;
- posséder Visual Studio .NET 2002 ou 2003 : les exemples seront réalisés avec Visual Studio .NET 2003, mais je n'ai remarqué aucune différence notable avec Visual Studio .NET 2002 ;
- enregistrer Crystal Reports for Visual Studio .NET : Vous devez enregistrer votre version de Crystal Reports. Ceci est obligatoire pour la partie déploiement de ce tutoriel.
Bonne lecture.
I. Fonctionnement d'un état▲
Avant de nous plonger dans le code et la création d'un état, nous allons voir quels sont les mécanismes qui entrent en jeu lors de la publication d'un état.
Un état peut-être considéré comme un « template ». Ce modèle va consommer des données brutes et générer un rapport qui contiendra les données mises en forme. Dans ce tutoriel, nous allons extraire des données en DotNET et nous en servir comme source de données pour notre état Crystal Reports. Le rapport généré sera affiché dans une fenêtre windows via un contrôle winform spécifique pour les rapports Crystal Reports.
Un état Crystal Reports peut consommer plusieurs types de sources de données :
Dans ce tutoriel nous ne parlerons que d'un seul type de source de données : Les DataSet ADO.NET.
Pourquoi ?
- Le DataSet ADO.NET est la seule source de données complètement indépendante du SGBD.
- Les données d'un DataSet ADO.NET peuvent être manipulées par votre application .NET.
- Un DataSet ADO.NET est sérializable et peut donc facilement être récupéré par remoting ou via un webservice.
Que reste-t-il aux autres sources de données ? On serait tenté de dire le gain de temps pour lier la source de données à l'état, mais nous allons rapidement voir qu'il n'y a vraiment rien de sorcier à utiliser un DataSet ADO.NET et que les fonctionnalités de notre IDE permettent de réaliser tout ça très rapidement.
II. Création du DataSet fortement typé▲
Nous allons commencer par créer un DataSet fortement typé. Pour que notre état puisse consommer les données de notre DataSet celui-ci doit être fortement typé. En effet, lors de la création de l'état il faut bien que Crystal Reports puisse déterminer le nom et le type des champs pour les données qui lui serviront à générer le rapport.
C'est le .xsd d'un DataSet fortement typé qui contient toutes ces informations.
Nous allons utiliser la base « Comptoir.mdb » fournie avec Access.
Pour créer rapidement un DataSet typé avec Visual Studio .NET :
- créer une nouvelle connexion de données dans la fenêtre « explorateur de serveurs » : clic droit sur connexion de données => ajouter une connexion ;
- ajouter un DataSet typé au projet : dans l'explorateur de solution => clic droit sur le projet => Ajouter => Ajouter un nouvel élément => Dataset. On l'appellera « DataSetTypEtats.xsd » ;
- dans l'explorateur de serveur, développer l'arbre de la connexion à la base Access => développer Tables => Glisser/Déposer la table « Produits » dans le concepteur de DataSet.
Voici le source du xsd du DataSet fortement typé obtenu :
<?xml version="1.0" encoding="utf-8" ?>
<
xs
:
schema
id
=
"DatasetTypEtats"
targetNamespace
=
"http://tempuri.org/DatasetTypEtats.xsd"
elementFormDefault
=
"qualified"
attributeFormDefault
=
"qualified"
xmlns
=
"http://tempuri.org/DatasetTypEtats.xsd"
xmlns
:
mstns
=
"http://tempuri.org/DatasetTypEtats.xsd"
xmlns
:
xs
=
"http://www.w3.org/2001/XMLSchema"
xmlns
:
msdata
=
"urn:schemas-microsoft-com:xml-msdata"
>
<
xs
:
element
name
=
"DatasetTypEtats"
msdata
:
IsDataSet
=
"true"
>
<
xs
:
complexType>
<
xs
:
choice
maxOccurs
=
"unbounded"
>
<
xs
:
element
name
=
"Produits"
>
<
xs
:
complexType>
<
xs
:
sequence>
<
xs
:
element
name
=
"Réf_x0020_produit"
msdata
:
AutoIncrement
=
"true"
type
=
"xs:int"
/>
<
xs
:
element
name
=
"Nom_x0020_du_x0020_produit"
type
=
"xs:string"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"N_x00B0__x0020_fournisseur"
type
=
"xs:int"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Code_x0020_catégorie"
type
=
"xs:int"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Quantité_x0020_par_x0020_unité"
type
=
"xs:string"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Prix_x0020_unitaire"
type
=
"xs:decimal"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Unités_x0020_en_x0020_stock"
type
=
"xs:short"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Unités_x0020_commandées"
type
=
"xs:short"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Niveau_x0020_de_x0020_réapprovisionnement"
type
=
"xs:short"
minOccurs
=
"0"
/>
<
xs
:
element
name
=
"Indisponible"
type
=
"xs:boolean"
minOccurs
=
"0"
/>
</
xs
:
sequence>
</
xs
:
complexType>
</
xs
:
element>
</
xs
:
choice>
</
xs
:
complexType>
<
xs
:
unique
name
=
"DatasetTypEtatsKey1"
msdata
:
PrimaryKey
=
"true"
>
<
xs
:
selector
xpath
=
".//mstns:Produits"
/>
<
xs
:
field
xpath
=
"mstns:Réf_x0020_produit"
/>
</
xs
:
unique>
</
xs
:
element>
</
xs
:
schema>
III. Création de l'état▲
Maintenant que nous avons créé le DataSet fortement typé, nous allons construire un état avec Crystal Reports.
Ce tutoriel n'est pas un cours sur l'utilisation de Crystal Reports. L'exemple utilisé sera très simple, et ne servira qu'à illustrer l'utilisation de Crystal Reports avec les DataSets ADO.NET. Pour plus d'informations sur les fonctionnalités de Crystal Reports, je vous renvoie sur le site officiel de Crystal Reports. Vous pouvez aussi poser vos questions relatives à l'utilisation de Crystal Reports sur le forum Générateur d'états.
Tout d'abord il faut ajouter un état Crystal Reports au projet. Dans l'explorateur de solution : clic droit sur le projet => Ajouter => Ajouter un nouvel élément.
Sélectionner « État Crystal Reports », on appellera cet état : « EtatTuto.rtp »
Nous allons ensuite utiliser l'expert d'état pour créer rapidement notre état.
Dans l'onglet « Données » développer l'arbre ADO.NET, puis le DataSet « DatasetTypEtat »
… puis faire « Insérer la table »
Dans l'onglet « Champs » faire « Ajouter » sur :
- Réf Produit ;
- Nom du produit ;
- Prix unitaire ;
- Unités commandées.
Passer directement à l'onglet « Diagramme ». Les onglets « Groupe » « Total » et « Nsup » permettent de classer les données et d'afficher des totaux par colonne et par groupe. Nous ne verrons pas ces fonctionnalités dans ce tutoriel.
Nous allons réaliser un diagramme sectoriel sur la quantité de produits commandés.
- Choisir un diagramme de type « sectoriel », faire « suivant ».
- Sélectionner « sur changement » puis ajouter le champ « Réf produit ».
- Sélectionner le champ « Unités commandées » dans « Afficher des valeurs ».
- Faire « Terminer ».
Voilà, notre état Crystal Reports est enfin créé. Voyons maintenant comment générer les rapports.
IV. Visualisation d'un état dans une application windowsform▲
Maintenant que nous avons notre DataSet fortement typé, et notre état Crystal Reports, voyons comment visualiser et générer un rapport.
Tout d'abord, ajoutez un contrôle CrystalReportViewer (onglet Windows Form) à votre form1
Nous allons ensuite ajouter une Drop Down List qui affichera toutes les catégories de produits, et un bouton de validation auquel on associera la génération et la visualisation de l'état en fonction de la catégorie de produit sélectionné.
On déclare nos objets d'accès aux données
System.
Data.
OleDb.
OleDbConnection cn;
System.
Data.
OleDb.
OleDbCommand cmd;
System.
Data.
OleDb.
OleDbDataAdapter myAdapter;
System.
Data.
OleDb.
OleDbDataReader rd;
CsharpEtats.
EtatTuto MonEtat;
// état crystal report
System.
Data.
OleDb.
OleDbParameter paramCmd;
CsharpEtats.
DatasetTypEtats DataMesProduits;
// DataSet que consommera l'état
Le générateur de code de Visual Studio .NET a généré les déclarations :
internal
System.
Windows.
Forms.
Button BtnOk;
internal
System.
Windows.
Forms.
ComboBox DdlCategorie;
private
CrystalDecisions.
Windows.
Forms.
CrystalReportViewer CRviewer;
Dans le form_load on remplit la liste déroulante :
private
void
Form1_Load
(
object
sender,
System.
EventArgs e)
{
// On remplit la liste déroulante
cn =
new
System.
Data.
OleDb.
OleDbConnection
(
@"Provider=Microsoft.Jet.OLEDB.4.0;"
+
"User ID=Admin;Data Source=C:\Program Files\Microsoft Office\Office\Exemples\COMPTOIR.MDB"
);
cmd =
new
System.
Data.
OleDb.
OleDbCommand
(
);
cmd.
Connection =
cn;
cmd.
CommandText =
"SELECT [Nom de catégorie] FROM Catégories"
;
cn.
Open
(
);
rd =
cmd.
ExecuteReader
(
);
while
(
rd.
Read
(
))
{
DdlCategorie.
Items.
Add
(
rd.
GetString
(
0
));
}
cn.
Close
(
);
DdlCategorie.
SelectedIndex =
0
;
}
Notez au passage le nom des tables et des champs qui est assez exotique ;) Bien sûr sur vos bases n'utilisez surtout pas ce type de nommage. Je vous conseille de faire un tour sur le site de sqlpro pour tout ce qui est règles de nommage pour vos tables/champs.
Maintenant voyons comment passer les données du DataSet à notre crystal report et comment le visualiser à l'aide du viewer.
private
void
BtnOk_Click
(
object
sender,
System.
EventArgs e)
{
DataMesProduits =
new
CsharpEtats.
DatasetTypEtats
(
);
paramCmd =
new
System.
Data.
OleDb.
OleDbParameter
(
"@cat"
,
DdlCategorie.
Text);
myAdapter =
new
System.
Data.
OleDb.
OleDbDataAdapter
(
"SELECT Produits.[Nom du produit],"
+
" Produits.[Prix unitaire], Produits.[Quantité par unité],"
+
" Produits.[Unités commandées], Produits.[Unités en stock] FROM (Catégories"
+
" INNER JOIN Produits ON Catégories.[Code catégorie] = Produits.[Code catégorie])"
+
" WHERE (Catégories.[Nom de catégorie] = @cat)"
,
cn);
myAdapter.
SelectCommand.
Parameters.
Add
(
paramCmd);
cn.
Open
(
);
myAdapter.
Fill
(
DataMesProduits.
Produits);
cn.
Close
(
);
MonEtat =
new
CsharpEtats.
EtatTuto
(
);
MonEtat.
SetDataSource
(
this
.
DataMesProduits);
CRviewer.
ReportSource =
this
.
MonEtat;
CRviewer.
Refresh
(
);
DataMesProduits.
Clear
(
);
DataMesProduits.
Dispose
(
);
}
Il y aurait bien sûr un travail de mise en forme à faire sur l'état Crystal Reports et la pertinence des données affichées est discutable. Mais le but de ce petit exemple est surtout de vous expliquer le principe d'utilisation de Crystal Reports avec Visual Studio .NET.
V. Déploiement▲
On pourrait penser qu'à ce stade, le plus dur a été fait, mais détrompez-vous ! Le déploiement d'un état Crystal Reports n'est pas simple du tout.
Surtout, pensez à tester vos setup sur des machines ou Visual Studio .NET n'est pas installé afin de vous assurer que les composants Crystal Reports s'installent bien.
Étudions le déploiement d'une application .NET utilisant Crystal Reports.
Tout d'abord créons un projet de déploiement :
- clic droit sur la solution dans l'explorateur de solution ;
- « Ajouter » ;
- « Nouveau Projet » ;
- « Projet de configuration ».
Maintenant, nous allons ajouter le projet CsharpEtats en sortie principale du projet. Nous ne rentrerons pas ici dans les détails de la création d'un setup avec Visual Studio .NET. Ce sujet sera l'occasion d'un autre tutoriel. Je cherche juste à vous montrer une problématique récurrente du déploiement d'états Crystal Reports :
- clic droit sur le projet dans l'explorateur de solution ;
- « Ajouter » ;
- « Sortie du projet » ;
- « Sortie Principale » ;
- OK.
À ce stade, on a créé un projet de déploiement « standard » qui permet de déployer une application winform classique. Le problème est que notre application utilise des composants Crystal Reports qu'il faudra enregistrer sur le poste client cible. Visual studio .NET détecte une dépendance et ajoute le module de fusion « Crystal_Database_Access2003.msm », mais ce n'est pas les seules dépendances que notre projet a avec Crystal Reports. Il faut donc ajouter des modules de fusion à la main :
- clic droit ;
- Ajouter ;
- Modules de fusion ;
- ajouter les modules de fusions suivants : « Crystal_regwiz2003.msm », « Crystal_managed2003.msm »,« Crystal_managed2003_fra.msm »,« VC_USER_CRT_71_RTL_X86_---.msm »,« VC_USER_STL_71_RTL_X86_---.msm ».
Vous devriez avoir :
Ensuite, il faut sélectionner « Crystal_regwiz2003.msm » aller dans propriété, développer « Merge Module Properties » et saisir votre licence key que vous avez eue après avoir enregistré Crystal Reports (gratuit).
Il vous suffit maintenant de générer le setup.
VI. Conclusion▲
Voilà, vous avez fini votre premier état Crystal Reports et vous êtes fin prêt pour le déployer. Rien de bien sorcier, mais il faut faire assez attention au niveau du setup.
J'espère que ce tutoriel vous aura permis de mieux appréhender l'utilisation de Crystal Reports avec Visual Studio .NET.
Vous pouvez télécharger les sources de ce projet ici [ftp://ftp2.developpez.be/developps/dotnet/CR/TutoEtatsCsharp.zip]. Le projet a été réalisé sous Visual Studio .NET 2003.