Business Geek

Aller au contenu | Aller au menu | Aller à la recherche

Business Intelligence

Fil des billets - Fil des commentaires

dimanche 28 septembre 2008

MS Days à Toulouse

Encore un nouvel événement Microsoft me direz-vous... Et bien oui et on ne s'en lasse pas, même si c'est événement n'est autre que le Microsoft Technet Tour de la fin d'année.

Au menu, des sessions et des échanges avec les speakers Microsoft sur les dernières technologies Microsoft : SQL Server 2008, Hyper-V, Visual Studio 2008, le Framework .NET 3.5, etc.

Le session sur la Business Intelligence avec SQL Server 2008 et Performance Point sera animée par votre serviteur. Je vous invite aussi à aller voir la session de Patrick Guimonet de Microsoft sur SQL Server 2008 dont le lancement en version finale a eu lieu pendant les vacances.

L'événement est gratuit et a lieu ces lundi et mardi (oui, le post arrive au dernier moment). Il vous reste donc quelques heures pour valider votre inscription et venir découvrir ou poser des questions sur les solutions Microsoft.

 

dimanche 31 août 2008

Analysis Services - Support du format monétaire dans Excel

Dans un projet décisionnel, il est nécessaire lors de la restitution des données de les formater. Par exemple, si vous présentez des données financières, il va falloir les afficher correctement.

Dans une architecture applicative classique, on laisse ce travail à la couche de présentation. Dans un contexte décisionnel, cette couche de présentation peut être Reporting Services qui gère le formatage mais ce peut-être aussi un client OLAP autonome comme Excel.

Excel sait gérer aussi le formatage mais c'est aux utilisateurs de le configurer via les options de la PivotTable :

Cette manipulation n'est pas à faire par les utilisateurs finaux, surtout pour des formats triviaux comme des devises.

 

Analysis Services permet d'ajouter des informations de formatage sur chaque cellule pour guider les clients OLAP dans leur réprésentation des données. Ainsi, quand on déclare un membre calculé par exemple, on ajoute la clause FORMAT_STRING décrivant le membre :

CREATE MEMBER CURRENTCUBE.[Measures].[Prix TTC]
AS [Measures].[Prix Vendu]*1.196,
FORMAT_STRING = "Currency"

Cette configuration se fait aussi via l'assistant :

 

Un client OLAP peut récupérer cette information en précisant une clause dans la requête MDX qu'il fait à Analysis Services.

SELECT {[Measures].[Prix TTC]} ON COLUMNS
FROM [CubSales]
CELL PROPERTIES VALUE, FORMAT_STRING

Excel précise bien cette clause dans ses échanges avec SSAS. Or il se peut qu'il n'arrive pas à représenter un membre calculé de type monétaire malgré l'information provenant du cube.

 

Une des solutions pour résoudre ce problème serait d'ajouter la clause FORMATTED_VALUE pour forcer le formatage des cellules par Analysis Services avant de renvoyer les données. On peut le vérifier avec une requête MDX dans Management Studio :

SELECT {[Measures].[Prix TTC]} ON COLUMNS
FROM [CubSales]
CELL PROPERTIES VALUE, FORMAT_STRING, FORMATTED_VALUE

 

Mais Excel ne permet pas de préciser ce paramètre donc il nous faut trouver une solution. Dans le cadre de données monétaires, il est important de connaître le pays pour déterminer la bonne devise. En effet, si mon cube contient des montants en euros, je ne veux pas voir des dollars si le client ou le serveur est en version US. En conséquence, il faut préciser la culture (Locale) en plus du formatage dans les méta-données des cellules. Ainsi, corrigeons notre membre calculé :

CREATE MEMBER CURRENTCUBE.[Measures].[Prix TTC]
AS [Measures].[Prix Vendu]*1.196,
FORMAT_STRING = "Currency", LANGUAGE = 1036 //fr-FR

 

Et là, plus de problème dans Excel pour afficher vos membres calculés en € de façon automatique. Attention, cette manipulation n'est pas possible avec le formulaire d'édition du membre calculé, il vous faudra passé par le script MDX de création.

dimanche 16 mars 2008

Migrer un cube Analysis Services 2000 vers 2005

Le propos de ce billet n'est pas de fournir un tutoriel complet sur la migration de cubes entre AS 2000 et 2005 mais juste de présenter les méthodes pour le faire. Je ne présenterai que les points d'entrée, je ne rentrerai pas dans le détails des incompatibilités entre les versions.

Méthode 1 : In-place upgrade

C'est la méthode qui paraît la plus simple mais qui pour moi s'avère la plus risquée. En effet, j'ai toujours l'impression de tout miser sur un coup de dé.

J'appelle cette méthode la Next->Next->Next, car c'est tout simplement le setup d'installation de SQL Server 2005 qui va effectuer la migration du cube en 2005 et faire la bascule en redémarrant le service. Le processus de migration est équivalent à la méthode présentée ci-dessous sauf que tout est automatisé. La coupure de service est donc assez réduite (hormis le fait qu'il faille refaire une process du cube).

Avantages : pas de modification des clients, courte coupure de service
Inconvénients : risque d'incompatibilités

PS : utilisez l'Upgrade Advisor de SQL Server 2005 pour avoir un aperçu des problèmes que vous pourriez rencontrer.

Méthode 2 : la migration

Contrairement à ce qu'on pourrait penser, la migration n'est pas une méthode compliquée. On ne doit pas refaire complètement ses cubes. Un assistant livré avec Analysis Services 2005 permet de monter un cube à partir des méta-données d'un cube sous 2000.

Cet assistant s'appelle le MigrationWizard.exe et se trouve dans %programfiles%\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE.
On y accède aussi dans Management Studio avec un clic-droit sur l'instance Analysis Service 2005 comme présenté dans ce screenshot.

L'assistant est très intuitif et le résultat est très bien (mis à part les incompatibilités connues).
Il ne reste plus qu'à ouvrir notre nouveau cube dans Business Intelligence Development Studio (oui, je sais, Visual Studio) pour apporter si besoin des petits correctifs et le tour est joué.

Avantages : simplicité, on maîtrise le passage entre les versions
Inconvénients : changement de la chaîne de connexion des clients

 

Conclusion

Le choix de la méthode dépend de nombreux facteurs comme les utilisateurs et l'utilisation qu'ils font du cube, les données sources, la volumétrie, la conception initiale sous 2000, les incompatibilités remontées par l'Upgrade Advisor... Dans tous les cas, une migration se planifie et se prépare : audit, test, test, test, migration !

samedi 16 février 2008

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.

lundi 28 janvier 2008

Requêter un cube Analysis Services depuis SSIS

On pourrait penser que requêter un cube OLAP avec Integration Services est trivial et pourtant, avec un collègue, nous nous sommes heurtés à quelques difficultés.

Première tentative :

Naïvement, nous créons une connexion de type OLE DB Provider for Analysis Services 9.0. On la branche sur un OLE DB Source et en guise de SQL Command, je tape ma requête MDX (les ventes par catégories depuis le DataWarehouse de AdventureWorks) :

SELECT NON EMPTY { [Measures].[Sales Amount] } ON COLUMNS,NON EMPTY { ([Dim Product].[Dim Product Category].[Dim Product Category].ALLMEMBERS ) } ON ROWS FROM [AdventureWorks]

A la confirmation, l'avertissement suivant apparaît :

[OLE DB Source [1]] Warning: The output "OLE DB Source Output" (11) references an external data type that cannot be mapped to a Data Flow task data type. The Data Flow task data type DT_WSTR will be used instead.

Soit, qu'il en soit ainsi, un WSTR me plait bien, de plus que la preview me montre bien le résultat attendu. Je termine mon package en dirigeant le flux vers un bête FlatFile.

A l'exécution, le warning réapparaît mais plus grave, le package plante violemment(lançant SQLDumper.Exe au passage).

La solution :

Il faut en fait passer par .NET et utiliser les providers "managed". On crée donc une ADO.NET Connection via un clic droit dans la zone des Connection Managers. Dans la liste des .NET Providers for OleDb, on choisit Analysis Services 9.0 (oui, le même mais en managé) et on le configure pour pointer sur notre cube.

Dans le Data Flow Task, on glisse un DataReader Source auquel on branche la connexion créée ci-dessus. Pas d'avertissement, on continue en branchant la sortie vers le fichier, on teste et ça marche immédiatement. Vous aurez peut-être juste besoin d'une conversion de type si vous n'êtes pas en UNICODE mais rien de difficile là-dedans (Data Conversion Transformation).

Merci à Julien sans qui je n'aurai jamais publié cet article (avant un moment).

 

PS : désolé, toutes les instructions sont en anglais car j'utilise une version US des produits, ce que je vous conseille même si vous êtes fan de la loi Toubon.

Affichage d'un tableau vide dans Reporting Services

Dans les newsgroups (US), de nombreuses personnes demandent comment gérer l'absence de données dans un tableau (ou un autre type de Data Region). Voici un petit condensé des solutions techniques...

Utilisation de NoRows

C'est la méthode la plus simple, si le DataSet lié à une DataRegion de type Table est vide, il est possible d'afficher un texte à la place du tableau grâce à la propriété NoRows. Le problème est que l'on ne peut pas modifier la mise en forme du texte et que rien d'autre ne s'affiche (pas d'entêtes de colonne). Aussi, si votre tableau mesure plusieurs centimètres de haut, l'espace reste réservé au rendu, laissant souvent un espace blanc et vide.

Utilisation d'une ligne cachée

L'idée ici est de garder les entêtes de colonne mais d'ajouter le texte explicatif d'absence de données. On ajoute une ligne de Header dans la Table. On écrit le texte dedans (avec une fusion de cellules au besoin). Puis on met une expression dans la propriété Visibility afin d'afficher la ligne uniquement s'il n'y a pas de ligne dans le DataSet:

=(CountRows()>0)

Attention, on doit retourner false si on veut cacher l'élément; il faut donc réfléchir à l'envers... Cette solution ne règle toujours pas le problème de l'espace vide avant l'élément suivant.

Utilisation d'une TextBox

On utilise le principe de la propriété Visibility pour cacher entièrement la Table si elle est vide Visibility.Hidden=(CountRows()=0). On place une TextBox contenant le message au-dessus de la Table et on lui applique une expression similaire dans sa propriété Visibility pour l'afficher à la bonne condition. La Table étant cachée, il n'y a pas d'espace utilisé et inversement.

 

PS : je n'ai pas réglé le cas où on souhaite afficher les entêtes sans l'espace vide. La propriété Visible n'est pas prise en compte sur une ligne de Table, il en est de même avec la propriété CanShrink. La solution que je vois est de recréer les entêtes dans un rectangle et d'utiliser la technique de la TextBox présentée ci-dessus.

 

mardi 22 janvier 2008

Hiérarchies non-naturelles avec Analysis Services

Ce webcast traite des hiérarchies dans les dimensions sous Analysis Services. On aborde la cas particulier des hiérarchies non-naturelles avec un exemple trivial d’une dimension Année-Mois-Semaine-Jour. Cette hiérarchie a la spécificité d’avoir une relation many-to-many entre 2 niveaux (mois-semaine). Voici une solution pour traiter le cas sans créer d’erreur de calcul dans le cube l’utilisant.

Hiérarchies non-naturelles avec Analysis Services
Hiérarchies non-naturelles avec Analysis Services

lundi 1 octobre 2007

70-445: je suis MCITP BID

Et voila, je suis devenu Microsoft Certified IT Professional: Business Intelligence Developer. J'ai réussi la certification 70-445.

Même si c'était le cas avant, n'hésitez pas à me solliciter (plutôt Bewise)  pour tous vos projets décisionnels.

Next Target : devenir MVP ? Pourquoi pas, on verra en 2008.

jeudi 27 septembre 2007

70-446

I got it

Ouf, après de nombreuses semaines de révision (c'est pour cette raison que le blog est un peu mort), je viens de passer la certification 70-446 : Designing a Business Intelligence Infrastructure by Using Microsoft SQL Server 2005 avec un joli score de 83%. Demain, je passe sa petite soeur la 70-445 et je croise les doigts pour obtenir le titre de MCITP BID (pour les néophytes : Microsoft Certified IT Professional: Business Intelligence Developer).

jeudi 6 septembre 2007

Le déploiement de rapports sous SSRS

Un article complet et sympathique sur les méthodes de déploiement de rapports sous SSRS (Reporting Services).

Sébastien Pertus, un collègue du pôle DGD (Décisionnel & Gestion de Données) dont je m'occupe chez Bewise, nous présente toutes les façons de passer un rapport en production. Avec cela, je suis sûr que vous trouverez le moyen qui convient le mieux à votre façon de travailler et à votre SI.

L'article est dispo sur le site de Bewise : Déploiement automatisé sous Reporting Services

- page 1 de 2