Introduction▲
Ce tutoriel a pour objectif de passer en revue les différentes étapes nécessaires à la mise en forme d'un rapport dans SSRS 2005. Il regroupe un certain nombre de fonctionnalités, des plus basiques comme le formatage des données aux fonctionnalités plus avancées telles que la coloration alternative de lignes via du code VB.
Nous aborderons ainsi successivement la mise en forme graphique du rapport, le formatage des données pour un affichage plus clair et le formatage du rapport lui-même pour l'affichage, l'impression et l'export. Enfin, une dernière partie abordera le paramétrage du ReportViewer au moyen de feuilles de style.
À noter, l'assistant de création de rapports va naturellement effectuer une certaine mise en forme (groupes de données, couleurs…), mais pour une vision plus claire, ce tutoriel part d'un rapport créé de toutes pièces sans assistant.
I. Mettre en forme le rapport▲
I-A. Grouper les données▲
Nous allons partir d'un tableau vierge auquel nous ajoutons simplement les champs et en-têtes qui nous intéressent. Commençons par lui mettre un cadre et colorons la ligne d'en-tête pour arriver à cela :
Ce simple tableau va nous servir de base pour la suite des événements.
La première étape va consister à créer un groupe afin d'afficher des sous-totaux, par zone géographique par exemple.
Dans les propriétés du tableau, il faut ajouter le groupe souhaité :
Les cases à cocher en bas de la fenêtre permettent de définir les options du groupe :
- saut de page avant ou après chaque nouvelle occurrence du groupe ;
- en-tête et pied du groupe ;
- répétition de l'en-tête ou pied du groupe.
En l'occurrence, un en-tête suffira.
Une nouvelle ligne, précédée d'un 1 apparaît alors dans le rapport. Pour l'instant, elle est vide. Une prévisualisation du rapport montre que maintenant les données sont groupées par zone, chaque groupe étant séparé par une ligne blanche.
Personnalisons la ligne d'en-tête de façon à inclure, la zone, un compte des différentes raisons de vente, et des sommes de quantité et montant.
D'autre part, il est inutile de répéter la zone sur chaque ligne, l'en-tête de groupe étant suffisant.
Après quelques ajustements de cadre, voilà le résultat :
I-B. La coloration alternative des lignes▲
Pour des raisons de lisibilité, nous allons maintenant colorer une ligne sur deux (dans le cas présent, ce n'est pas primordial, mais lorsqu'il y a beaucoup de données en ligne et colonne, c'est très important pour la lisibilité).
Pour ce faire, deux possibilités.
Il est possible d'utiliser une formule simple qui va définir la couleur de fond de la cellule en fonction du n° de ligne :
=IIF(RowNumber(Nothing) Mod 2=0, "LemonChiffon","White")
Il est possible de jouer sur le Modulo, Mod 3 colorera par exemple une ligne sur 3…
Il est également possible de jouer sur le scope du RowNumber. En laissant nothing, le RowNumber sera calculé sur l'ensemble du tableau. On peut y mettre comme scope le groupe de données de Zone pour que le RowNumber soit calculé en fonction du groupe. L'avantage est évident, si le nombre de lignes est impair, la 1re ligne du groupe commencera toujours de la même couleur (sans scope, ce sera la continuité des lignes précédentes).
Cette formule fonctionne également pour les autres paramètres de couleurs comme le texte ou le cadre. En inversant les couleurs, on pourra donc alterner cadre et fond.
Dans certains cas, le Modulo du RowNumber peut donner des résultats incohérents (si des filtres sont appliqués au rapport par exemple). Dans ce cas, on peut, par du code VB inclus dans le rapport, créer une fonction qui va définir la couleur de fond.
Le code en question vient du site Technet de Microsoft (la page ne semble plus exister maintenant).
Private
bOddRow AS
BOOLEAN
FUNCTION
AlternateColor
(
ByVal
OddColor AS
String
, _
ByVal
EvenColor AS
String
, ByVal
Toggle AS
BOOLEAN
) AS
String
IF
Toggle Then
bOddRow =
NOT
bOddRow
IF
bOddRow Then
RETURN OddColor
Else
RETURN EvenColor
End
IF
End
FUNCTION
Il suffit de coller ce code dans l'onglet code des propriétés du rapport :
Puis d'appeler cette fonction dans la propriété BackgroundColor avec la formule suivante :
=Code.AlternateColor("LemonChiffon", "White", True)
pour la 1re colonne puis
=Code.AlternateColor("White", "LemonChiffon", True)
Ce code va simplement alterner les couleurs en fonction de la précédente. Il est bien sûr possible de le modifier pour varier les effets.
Par exemple, en voilà un modifié par mes soins pour effectuer la coloration au niveau d'un groupe de données :
Private
bOddRow AS
BOOLEAN
, n AS
Integer
FUNCTION
AlternateColor
(
ByVal
OddColor AS
String
, _
ByVal
EvenColor AS
String
, ByVal
Toggle AS
BOOLEAN
, ByVal
groupe AS
String
) AS
String
'On inverse la couleur de base à chaque ligne
bOddRow =
Not
bOddRow
'Si le n° de projet est le même qu'à la ligne précédente, on réinverse la couleur
If
groupe =
n then
bOddRow =
Not
bOddRow
'n prend la valeur du n° de projet de la ligne
n =
groupe
'En fonction de bOddRow, on renvoie la couleur
If
bOddRow Then
Return OddColor
Else
Return EvenColor
End
If
End
Function
Cette modification requérant davantage de paramètres, il faudra adapter la formule en conséquence.
=Code.AlternateColor("LemonChiffon", "White", True, Fields!Sales_Territory_Group.Value) (le groupe en l'occurrence).
I-C. Le DrillDown▲
Le DrillDown permet de n'afficher que certaines données en laissant la possibilité à l'utilisateur d'afficher ou non le détail.
Cette fonctionnalité est pilotée par la propriété Hidden des différents éléments du rapport. Elle se situe à deux niveaux : les données et le tableau.
Deux paramètres sont à prendre en compte :
- l'état initial de l'élément (masqué ou pas) ;
- l'élément du tableau qui va changer cet état (la cellule qui va contenir le +).
Par exemple :
Mettons la ligne de détail du rapport en invisible :
Le rapport n'affichera que l'en-tête du groupe Zone, tout en masquant les détails qui peuvent être vus en cliquant sur le +.
Dans certains cas (les matrices notamment), les lignes seront masquées, mais resteront présentes ce qui donnera un espace vide. Même remarque pour les colonnes dans certains cas.
Il est également possible de régler cette propriété au niveau des groupes du tableau dans les propriétés de celui-ci. Les paramètres sont les mêmes :
Dans l'exemple précédent, l'élément qui change l'état initial est la cellule contenant le nom de la Zone, répétée x fois. Il est tout à fait possible d'entrer une cellule qui n'est pas répétée, qui permettra de piloter tous les groupes masqués à la fois (« Show all »).
Très utile si le rapport comporte beaucoup de groupes, car il est fastidieux de cliquer 15 fois pour afficher tous les détails.
II. Formater les données▲
II-A. Définir le format▲
Par défaut, les valeurs sont affichées telles quelles, ce qui n'est pas forcément esthétique ou pratique. On va donc les formater pour les rendre plus agréables à lire.
Le formatage concerne toutes les données, mais ce sont surtout les données chiffrées et les dates qui nécessitent un formatage.
Ce formatage peut se faire au niveau d'une case de tableau avec un clic droit/propriétés/format :
En cliquant sur le bouton de format code, une fenêtre va permettre de choisir des formats par défaut ou d'en ajouter soi-même.
II-B. Les formats standard▲
Les formats par défaut ont l'avantage d'être des formats standards qui vont s'adapter à l'utilisateur en fonction de sa langue. Par exemple une date, jour/mois/année en français sera affichée en mois/jour/année sur un poste américain.
La liste des formats standards numériques est disponible ici :
Chaines de formats numériquesChaînes de formats numériques
Pour les dates :
Chaines de format DateTime standardChaînes de format DateTime standard
Il est possible de préciser le nombre de décimales affichées pour la plupart des formats numériques. Par exemple P2 pour un pourcentage avec deux décimales.
II-C. Les formats personnalisés▲
Il est également possible de personnaliser les formats. Les formats de date resteront en fonction des paramètres linguistiques de l'utilisateur. En revanche, les formats numériques seront figés avec les paramètres fixés (séparateurs de milliers, séparateurs de décimales).
Par exemple :
dd/MM/yyyy pour une date au format 25/12/2008
dd MMM yyyy pour une date au format 25 dec 2008 (le mois viendra en fonction de la langue utilisateur)
dd MMMM yyyy pour une date au format 25 décembre 2008 (le mois viendra en fonction de la langue utilisateur)
### ### ##0,00 pour une valeur au format 123 456,78 ou 123 456,00 ou 0,00 (attention au nombre de # au-delà on aurait 123456 789 123 456,78 au lieu de 123 456 789 123 456,78)
On peut aussi passer les paramètres à la volée dans le tableau. C'est utile pour concaténer plusieurs valeurs de formats différents. On utilisera la fonction Format dans ce cas.
Par exemple :
="Rapport exécuté le " & Format(Today(),"dd/MM/yyyy")
Affichera : Rapport exécuté le 26/10/2008
Il est également possible de conditionner la valeur d'une cellule de tableau en fonction de sa valeur.
Par exemple, on veut afficher une cellule vide à la place de 0. On mettra donc la formule :
=IIF(Fields!Internet_Order_Quantity.Value=0,nothing,Fields!Internet_Order_Quantity.Value)
directement dans le tableau.
On peut bien sûr décliner à l'infini à la manière d'Excel.
III. Préparer son rapport pour l'affichage et l'impression▲
III-A. Format de la zone de travail▲
Lors de l'affichage, le Reportviewer va afficher non pas le ou les tableaux, mais la zone de travail. Si celle-ci est trop large, la page sera trop grande pour l'affichage à l'écran.
L'effet sera le même à l'impression. Il convient donc d'ajuster la taille de la zone de travail au rapport :
Il va falloir ensuite définir deux propriétés qui sont souvent confondues :
la taille de la page d'affichage et la taille de la page d'impression.
III-B. La taille de la page d'affichage▲
La taille de la page d'affichage va permettre de définir la taille de la page à l'écran. Une fois la taille atteinte, le Reportviewer va ajouter une 2e page lors de la visualisation.
Cette propriété se définit dans les propriétés layout :
Pour les voir, il suffit de cliquer dans la zone vide sous la zone de travail. Ce qui nous intéresse particulièrement est la propriété « Interactive Size ». Elle comporte deux paramètres, largeur et hauteur. La largeur n'est pas très intéressante, mais la hauteur va définir les sauts de page lors de la visualisation. Pour n'afficher le rapport que sur une seule page, il suffit de mettre la hauteur à 0. Ainsi, même si le rapport est très grand, il ne sera affiché que sur une seule page et l'utilisateur n'aura pas à naviguer entre les pages pour voir l'intégralité de son rapport.
Attention toutefois, plus le rapport est grand, plus il mettra de temps à s'afficher.
III-C. La taille de la page d'impression▲
La taille de la page d'impression se trouve dans les propriétés mêmes du rapport :
On va pouvoir définir les marges et surtout la taille du papier.
Pour une impression en paysage, il suffit d'inverser les valeurs.
Ces paramètres seront pris par défaut lors d'une impression du rapport ou d'un export PDF.
Par défaut, les valeurs sont exprimées en Inches sur une installation en anglais US, mais il suffit de remplacer « in » par « cm » pour que l'unité soit les centimètres.
Ces deux tailles de pages sont indépendantes et il faut régler les deux pour obtenir le résultat souhaité.
IV. Préparer son rapport pour l'export vers Excel▲
L'export vers Excel va garder la mise en forme du rapport, mais va l'interpréter en termes de cellules ce qui peut donner lieu à des cellules fusionnées et des colonnes masquées. Le rapport gardera son esthétique, mais pour retravailler les données derrière, ce n'est pas pratique.
Ajoutons un simple titre dans une textbox et exportons vers Excel :
Dans Excel, on obtient :
Pour commencer, on voit qu'il exporte également les drilldown. Pour information, cela correspond dans Excel à un plan (Données/Grouper et créer plan) que l'on peut supprimer si besoin est.
On note également un certain nombre de petits soucis :
- la colonne A correspond à l'espace laissé à gauche du rapport ;
- les colonnes B et C sont fusionnées dans la 1re colonne du rapport ;
- les colonnes C et D sont fusionnées pour le titre ;
- les colonnes D et E sont fusionnées dans la 2de colonne du rapport. Cela correspond à la fin de la textbox du titre.
On voit donc que l'export vers Excel n'est pas parfait. Il faut donc toujours le tester. Dans ce cas, c'est un rapport simple, mais si le rapport comporte plusieurs tableaux superposés, cela peut devenir rapidement compliqué à gérer.
Dans cet exemple, le plus simple sera d'incorporer le titre directement dans le tableau.
On peut également en profiter pour ajouter quelques informations utiles comme la date de l'exécution du rapport ou la valeur des paramètres choisis. Une fois sauvegardé sur son ordinateur, l'utilisateur pourra ainsi savoir à quoi correspondent les chiffres qu'il a sous les yeux.
Un certain nombre de valeurs par défaut sont disponibles :
On pourra également afficher des valeurs venant de l'extérieur. Un exemple tout bête serait, au moment de l'intégration des données, de mettre à jour une table avec la date d'extraction qu'il suffira de requêter en SQL pour rapatrier la date de mise à jour des données et afficher cette date dans le rapport.
Le résultat :
Et ce sera parfaitement exportable sous Excel.
Pour afficher la valeur des paramètres, il faut afficher leur Label et non la Value. Dans le cas d'un paramètre multivalue, il faudra faire un Join et indiquer un séparateur.
Par exemple :
="Produits : " & join(Parameters!ProductCategory.Label,", ")
donnera :
« Produits : Accessoire, Composant » si j'avais sélectionné deux valeurs.
V. Design du ReportViewer▲
Le composant ReportViewer utilisé pour afficher les rapports dans un navigateur web est basé sur une feuille de style CSS qui peut être modifiée pour, par exemple, appliquer une charte graphique.
La feuille CSS ne va avoir un impact que sur les aspects graphiques et aucunement sur l'organisation des éléments. On ne pourra pas, par exemple, mettre les listes de paramètres sur trois colonnes. On pourra en revanche changer les espacements des listes, changer la couleur de fond, les polices…
Il y a deux façons d'appliquer une feuille de style.
V-A. Modifier la configuration du serveur de rapports pour y inclure une feuille de style▲
Pour cela, il faut aller dans le fichier RSReportServer.config qui se trouve dans le dossier …\MSSQL.3\Reporting Services\ReportServer et y ajouter la ligne
<HTMLViewerStyleSheet>Mafeuille</HTMLViewerStyleSheet>
En remplaçant Mafeuille par le nom de la feuille à utiliser, sans extension.
Avant toute modification, ne pas oublier de faire une sauvegarde de ce fichier.
Un restart du service Reporting Services sera probablement utile.
V-B. Passer la feuille de style en paramètre dans l'URL du rapport▲
Cette solution peut être utile dans le cas de l'utilisation de plusieurs feuilles de style. Il suffira d'ajouter &rc:Stylesheet=Mafeuille dans l'URL du rapport.
Exemple :
http://MonServeur/ReportServer/Pages/ReportViewer.aspx?%2fAdventureWorks+Sample+Reports%2fMonRapport&rs:Command=Render&rc:Stylesheet=Mafeuille
V-C. La feuille de style CSS▲
Les feuilles sont à mettre dans le dossier …\MSSQL.3\Reporting Services\ReportServer\Styles. Microsoft fournit une feuille standard HtmlViewer.css qui peut être utilisée comme modèle, mais la modifier directement ne changera rien si cette feuille n'est pas appelée.
À l'ouverture, on peut voir un certain nombre de balises, mais la documentation sur celles-ci est assez mince. Il faudra donc jouer avec pour voir les impacts. Heureusement, les noms sont relativement explicites.
Cette feuille n'aura un impact que sur le composant ReportViewer, qui inclut la zone de paramètres, la barre d'outils et la zone de rapport.
Le ReportManager (le portail par défaut) peut aussi être personnalisé, mais cette fois, c'est dans le dossier …\MSSQL.3\Reporting Services\ReportManager que ça se passe.
Conclusion▲
Avec ces différents éléments, il est possible de produire un rapport visuellement agréable et pratique à utiliser. Il ne faut pas oublier que 50 % de l'acceptation des rapports par les utilisateurs vient de l'esthétique et de la facilité de lecture.
Remerciements▲
Un grand merci à Fleur-Anne pour ses précieux conseils de marraine.