Faire un cumul avec Reporting Services

Erratum :

J’étais fatigué (retour de TechDays ??) quand j’ai écrit cet article car il y a une solution beaucoup plus simple (que je connaissais en plus). Je n’ai pas voulu écouter la petite voix dans ma tête qui me disait « abruti, abruti » quand j’ai cité la fonction Previous. Bref, la solution est :

=RunningValue(Fields!SubTotal.Value, Sum, Nothing)

Mais je vous invite à lire la solution proposée ci-dessous car elle est utile pour de aggrégats un peu custom (et puis pour dire que je n’ai pas gratté pour rien).

Article Original

Dans cet article nous allons voir comment faire une somme cumulée dans un rapport. Le principe est simple, j’ai des ventes dans le temps et pour chaque date, je veux le cumul depuis la première date.

Reporting Services n’offre pas cette fonctionnalité en natif mais nous allons mettre en place les élements pour le suporter. Sans vouloir gâcher la surprise, je peux déjà vous annoncer que l’on va passer par du code .NET ajouté au rapport.

Pour commencer, voyons ce que nous offre Reporting Services comme fonction en rapport avec notre besoin. Il y a la fonction Previous qui permet de récupérer des données dans la ligne précédente. Cependant, cela ne marche plus à partir de la 3eme ligne car la fonction ne remonte pas plus haut.

L’idée pour résoudre cette problématique est d’utiliser une variable qui va tenir le cumul depuis la première ligne. A chaque ligne, on ajoute la valeur en cours. Pour garder une variable, on doit passer par le code .NET.

Pour ce faire on passe par la fenêtre de propriétés du rapport, dans l’onglet Code.

Oubliez le confort de l’Intellisense, vous n’êtes pas dans Visual Studio, l’éditeur ressemble plutôt à Notepad. En espérant que Reporting Services 2008 apporte des améliorations dans ce sens (comme pour Integration Services). En plus, vous êtes limité uniquement à VB.NET comme langage.

Quant au code en lui-même il est assez simple. On garde un variable Shared (static) et on fournit une petite fonction pour mettre à jour et retourner le cumul.  Ici j’ai choisi le type Decimal car je souhaite retourner une somme d’argent. Rien de plus simple :

Shared cumul As Decimal = 0.0
Public Shared Function GetCumulativeSum(ByVal currentValue As Decimal) As Decimal
  cumul += currentValue
  Return cumul
End Function

Reste à utiliser ce code dans le rapport. Pour cela, on utilise une Expression dans un élément de notre DataRegion :

=Code!GetCumulativeSum(Fields!SalesAmount.Value)

 

Un des problèmes est que l’on ne peut pas utiliser cette technique de cumul à différents endroits. En effet, on ne repart jamais à zéro. Plutôt que de tenter de réinitialiser le cumul dans la première ligne d’une DataRegion, on préfèrera l’utilisation d’un dictionnaire dans le Custom Code. Voici le code utilisant un dictionnaire :

Shared cumuls As System.Collections.Generic.Dictionary(Of String, Decimal) = _
     New System.Collections.Generic.Dictionary(Of String, Decimal)
Public Shared Function GetCumulativeSum(ByVal currentValue As Decimal, ByVal sumKey As String) As Decimal
  If Not cumuls.ContainsKey(sumKey) Then
    cumuls.Add(sumKey, 0.0)
  End If
  cumuls.Item(sumKey) += currentValue
  Return cumuls.Item(sumKey)
End Function

Dans le rapport, on utilisera l’expression suivante :

=Code!GetCumulativeSum(Fields!SalesAmount.Value, "salesInChart")
...
=Code!GetCumulativeSum(Fields!TaxAmount.Value, "taxInMatrix")

Note : pour faire du C#, il faudra coder la fonction dans une assembly et la référencer dans le rapport.

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s