lundi 7 décembre 2009

[SSAS] Utiliser les viewers Data Mining dans un BackOffice Winforms

Petit post très court pour donner des idées. Pour intégrer les viewers de modèles de Data Mining disponibles dans Visual Studio au sein d'Excel, les développeurs de Redmond ne les ont pas recodés. Ils ont simplement profité du fait que ceux ci sont disponibles en tant que composants Winforms et que vous pouvez faire de même, à savoir les réutiliser dans vos applications.
Il suffit pour cela de les ajouter à la Toolbox Winforms, en allant chercher l'assembly Microsoft.AnalysisServices.Viewer.dll qui doit se trouver dans le dossier Common7\IDE\PrivateAssemblies de votre installation de Visual Studio.



A vous les jolis backoffices!
A bientôt!

mercredi 25 novembre 2009

[SSAS] Assembly ExcelMDX sur le serveur SSAS?


Une petite note très rapide sur l'assembly ExcelMDX: on m'a encore demandé pourquoi il na marchait pas sur le serveur de production d'une entreprise...
ExcelMDX comme son nom l'indique est associé à... Excel.
Il nécessite Excel pour fonctionner ce qui est rarement - qui a dit jamais? - le cas pour une configuration de production. Alors oui il apporte quelques fonctions salutaires au MDX mais il vaut mieux ne jamais l'utiliser sous peine de faire face à des suprises au déploiement.
C'est un choix d'architecture pour le moins... étonnant.
Pour un utilisateur de MDX la seule solution est de remplacer les fonctions ExcelMDX: en se débrouillant avec le MDX existant ou en codant une procédure stockée managée.
A bientôt!
PS: Le lien de cette bizarrerie sur Connect, posté initialement par Greg Galloway. Le walkthrough MSDN de création de procédures stockées si cela peut vous aider. Merci à Gurvan et à son blog de haut vol de m'y avoir fait repenser.

lundi 23 novembre 2009

[SSAS] L'opérateur UNION manquant en DMX

Il vous est peut être arrivé de vouloir intégrer un Forecast généré avec Analysis Services Data Mining dans une application. C'est très joli à présenter, et ça l'est encore plus au sein d'un rapport Reporting Services.




Malheureusement, l'instruction PredictTimeSeries() qui gouverne la sortie d'un modèle de type TimeSeries ne permet que d'effectuer des sorties de données passées OU futures mais pas les deux mixées... Or l'ami Reporting Services ne supporte qu'un DataSet par DataRegion donc impossible de réaliser nativement une belle courbe avec le réel suivi du forecast...

Jamie Mc Lennan l'architecte du produit, propose sur son blog de réaliser une SP managée pour rempalcer PredictTimeSeries. Solution efficace et que j'ai déjà testé, mais qui masque à mon avis un problème de DMX, le manque d'opérateur UNION en n'adressant qu'une seule problématique induite.

En codant un petit bout de C# on arrive pourtant facilement à obtenir un pseudo opérateur union parfaitement fonctionnel, d'abord en écrivant une méthode d'exécution de code DMX renvoyée sous forme de DataTable:

private DataTable ExecuteQuery(string query)
{
using (AdomdCommand cmd = new AdomdCommand(query))
{
AdomdDataReader dr = cmd.ExecuteReader();
DataTable destinationDt = new DataTable();
DataTable schemaDt = dr.GetSchemaTable();
foreach (DataRow schemaDr in schemaDt.Rows)
{
destinationDt.Columns.Add((string)schemaDr["ColumnName"], (Type)schemaDr["DataType"]);
}

DataRow currentDr = null;
while (dr.Read())
{
currentDr = destinationDt.NewRow();
for (int i = 0; i < dr.FieldCount; i++)
{
currentDr[i] = dr[i];
}
destinationDt.Rows.Add(currentDr);
}
}
return destinationDt;
}


Qu'il suffit ensuite d'utiliser avec cette méthode:

private DataTable ForgeUnionDMX(params object[] dmxQueries)
{
DataTable t1 = this.ExecuteQuery(dmxQueries[0].ToString());
for (int i = 1; i < dmxQueries.Length; i++)
{
t1.Merge(this.ExecuteQuery(dmxQueries[i].ToString()));
}
return t1;
}

Malheureusement, et c'est le seul point que je n'ai pas réussi à résoudre, il semble qu'Analysis Services soit incapable de reconnaitre les procédures stockées acceptant un paramètre de type params (ParamArray en VB).
Ce n'est donc pas cette méthode qu'il faut exposer mais plutôt autant d'alias qu'on souhaite accepter de paramètres...

public DataTable UnionDMX(string dmxQuery1, string dmxQuery2)
{
return this.ForgeUnionDMX(dmxQuery1, dmxQuery2);
}
public DataTable UnionDMX(string dmxQuery1, string dmxQuery2, string dmxQuery3)
{
return this.ForgeUnionDMX(dmxQuery1, dmxQuery2, dmxQuery3);
}
Sale et dommage, mais inéluctable semble-t-il: Greg Galloway et Darren Gosbell ont fait de même à de nombreux endroits dans le projet ASSP.

Voilà à vous de coller ça dans un projet C# et de l'essayer: vous allez voir c'est très joli et cela constitue un argument assez immédiat en faveur de ce type d'applications

A bientôt.

mardi 10 novembre 2009

[SQL] R2 CTP3 Go Go Go!

SQL Server 2008 R2 November CTP est disponible! Go!

Cette version est feature complete. Pour un résumé des nouveautés, allez sur l'excellent post de Teo Lachev.

Bon test!

[SQL] On ne parle que de Gemini, on oublie StreamInsight!

C'est vrai, depuis quelques mois on ne parle que de Gemini ou plutôt PowerPivot la fonctionnalité de D-OLAP à la sauce Microsoft introduite dans Excel 2010 sur 2008 R2. Mais c'est oublier une autre nouveauté à mon sens presque plus critique: StreamInsight, le moteur de CEP (Complex Event Processing).

CEP kézako?

Le CEP en fait est facilement compréhensible par son nom: il s'agit de gestion d'évènement complexes. Qu'est ce qu'un évènement complexe? Typiquement une composition d'évènements simples détectables dans des bases de données, sur des senseurs...

Un senseur qui passe dans le rouge est facile à détecter, la réaction est facile à coder. La programmation à base d'évènements simples est la base du développement moderne. En revanche définir, détecter et traiter des compositions d'évènements est bien plus complexe car généralement orienté business.

Ce sont des règles métier qui lui donnent une cohérence, une existence. Lorsque l'évenement est détecté, il déclenche un processus de notification, d'action.
Ces règles métier sont appelées Query Logic sous StreamInsight et définies en LINQ.

Un moteur de CEP comme StreamInsight fournit donc des interfaces d'E/S et les librairies .NET nécessaires pour écrire d'une part les Streams d'entrée et de sortie et d'autre part la Query Logic de ces évènements complexes.



Des exemples?

Oui, autant que vous le souhaitez! LINQ de part son requêtage aussi puissant que SQL permet de définir des aggrégations et donc des KPI: il est possible de réagir en temps réel, sans passer par une phase de retraitement des données, au changement d'un KPI comme celui-ci

var MoyenneCA = from Groupe in InputStream.Snapshot()
select new { avg = Groupe.Avg(Mesure => Mesure.CA))};


Encore mieux: il est possible de combiner les sources des Streams et d'interroger un modèle de Data Mining pour vérifier la conformité en temps réel, et sans stocker de données!

Et on peut tester?


Bien sûr! Pour le moment je n'ai testé que des choses très simples (Streams SQL qui envoient à un modèle de DM, Streams fichier qui sont traitées par des KPI simples...) mais à vous de jouer pour des choses encore plus techniques!
SQL Server 2008 R2 August CTP est disponible sur Technet et n'attend que vous!

Bon test et à bientôt!

dimanche 8 novembre 2009

[SSAS] VisualTotals et Excel 2007

Je voulais rappeler quelques informations au sujet de la gestion des VisualTotals sous Excel 2007. Pour rappel un VisualTotal - ou "total visuel" qui dit bien ce que c'est - consiste simplement à afficher comme total d'un niveau aggrégé une valeur dépendante de la sélection.

En clair, dans une PivotTable, si je n'affiche que les produits A, B et C dans ma dimension Produit avec la mesure NbVentes, j'aurai au niveau supérieur la somme des ventes des produits A, B et C et non pas de tous les produits de même niveau que A, B et C. Ce qui peut être voulu ou pas selon le type de rapports.

Cette fonctionnalité n'est pas désactivable en 2007, alors qu'elle l'était en 2003. C'est un effet de bord d'un changement de mode de requêtage qui intervient pour résoudre les problèmes de multisélection dans les filtres.

En AS 2000, pour filtrer (slicer) sur un set (par exemple quelques pays) il n'est pas possible d'écrire cela:

SELECT
...
WHERE ({[Pays].[Pays].[Pays].&[UK],[Pays].[Pays].&[FR]})

La multiselection dans le slicer n'est pas supportée. C'est une fonctionnalité 2005 et supérieure. En 2003 (PivotTables v10), les filtres sont donc implémentés à la "manière 2000", - c'est pareil dans ProClarity en fait - les filtres sont générés dans des membres calculés et positionnés dans le slicer.
WITH MEMBER [Pays].[MonFiltre] AS
Aggregate

Aggregate ({[Pays].[Pays].[Pays].&[UK],[Pays].[Pays].&[FR]})
...
SELECT
...
WHERE
([Pays].[MonFiltre])
(Ce qui implique de fameux problèmes avec le CurrentMember - le CurrentMember de ma hiérarchie Pays est où dans le cas précédent? C'est un set! - bien explicités par Mosha dans son fameux papier).
Le fait d'autoriser cette multisélection dans le slicer n'a pas été exploité dans Excel 2007. Pour permettre des fonctionnalités de filtrage plus avancés en déléguant correctement les tâches de filtrage au moteur AS, Excel utilise les sous-requêtes (subselect) .La multisélection est donc gérée par un sous cube là aussi une nouvelle fonctionnalité introduite après 2000:

SELECT
...
FROM
(
SELECT
({[Pays].[Pays].[Pays].&[UK],[Pays].[Pays].&[FR]}) ON 0
FROM [MonCube]
)

L'effet de bord de gérer cette multisélection dans un sous-cube est donc de ne générer que des totaux visuels (VisualTotals): on ne ramène jamais les totaux du cube.

Pour faire cela, si vous en avez un besoin impérieux il existe une seule solution: créer des PivotTables en version précédente.

Cela peut se faire de trois manières:
- En VBA en créant une Macro qui créera la PivotTable en version 10
- En VSTO sur le même modèle (recréer un bouton "créer PivotTable" pour forcer l'utilisation de la version précédente, je l'ai fait, c'est assez élégant).
- En utilisant le mode de compatibilité d'Excel, qui va créer la PivotTable en version précédente
: attention cependant si vous enregistrez la feuille en compatibilité vers le mode standard, les PivotTables seront marquées pour mise à jour, et mises en version 12 au prochain Refresh, c'est à vous de l'interdire en... VBA en utilisant la propriété UpgradeOnRefresh des PivotTables.
(Merci au blog des développeurs d'Excel pour cette précision qui m'a évité de devenir fou :)

En espérant que ce post ait pu être utile à quelques uns.
A bientôt!

mardi 27 octobre 2009

[SSAS] 2008 et les précédences de calcul

Il semble vraiment que la tendance amorcée depuis 2005 avec une simplification des règles d'évaluation des calculs MDX se perpétue en 2008.
Tout cela remettant en cause pas mal de modes de développement choisis - à bon ou mauvais escient - sur les versions précédentes. La migration 2005/2008 peut donc poser des problèmes à certains dans des cas assez particuliers, sur lesquels je voulais attirer votre attention et dont je possède un exemple assez frais.

Si vous parcourez BOL (http://msdn.microsoft.com/fr-fr/library/ms143742.aspx) vous tomberez sur ceci:

Si un cube contient une dimension avec des formules de niveau personnalisées ainsi que des dimensions avant et après avec des formules de membre personnalisées et/ou des opérateurs unaires, il se peut qu'il retourne des résultats différents de ceux des versions précédentes de Analysis Services. Cette situation se produit car le calcul des règles de précédence a changé.

Intéressant. En se plongeant dans les articles de BOL sur le SOLVE_ORDER et dans l'excellent AS Unleashed, on constate en effet un gros effort de documentation de ces règles de précédence et de calcul, qui contraste avec le peu de différences entre les versions de documentation sur les autres aspects du moteur.

Pour résumer il semble que les bidouillages à base de CALCULATION_PASS et de SOLVE_ORDER voient leurs instants comptés dans le script MDX du cube, au bénéfice de l'ordonnancement de celui-ci. Cela se confirme par la dépréciation des CELL CALCULATION au profit des assignments qui eux ne disposent pas de propriétés d'ordre modifiables.
Certes il n'est pas vrai que l'ordre du script soit toujours l'ordre d'évaluation - le MDX n'est pas du C#, cf l'utilité de FREEZE - mais il bénéficie au moins d'une prédictivité plus évidente.

Dans le cas de combinaisons avec des HighestPass (Unary, Custom Rollup) l'ordre de résolution des calculs est maintenant plus clair: entre une CR et un ensemble de calculs donné du script on comprend désormais quelles sont les règles de précédence, même si elles sont parfois troublantes. Il reste possible de jouer avec le SOLVE_ORDER dans la CustomRollupPropertyColumn mais là encore l'ordre n'est pas garanti (en effet le SOLVE ORDER n'est pas le seul critère d'évaluation, cf http://msdn.microsoft.com/en-us/library/ms145539.aspx).

Ces changements peuvent parfois poser des problèmes: le fonctionnement peu clair de 2005 obligeait à des développement empiriques - comme celui sur lequel je travaille en ce moment.
L'ordre de calcul entre deux expressions MDX et une C.R.Formula était pour le moins étrange: en 2005 la rollup s'évaluait au beau milieu des calculs de script sans que l'on en comprenne la raison.
Une fois migrée en 2008, la rollup s'évalue dans mon cas avant conformément aux règles énoncées et cela peut poser des problèmes si on considérait la précédence 2005 comme acquise.

La réponse de Microsoft à ce sujet est de tenter de ne jamais mélanger assignments, membres calculés et CustomRollup sur un même calcul car même mieux documentées ces règles peuvent avoir un comportement défiant la logique initiale.