I. Introduction▲
Depuis la version XI de BO, l'accès au référentiel (stocké base de données) de BO est crypté et de ce fait, on ne peut plus y accéder pour en extraire les métadonnées :
- liste des classes et objets de l'univers ;
- propriétés de chaque objet (source SQL, dimension, etc.).
Faire ces listes permettait de faire des comparaisons entre univers (exemple, entre une version de développement et une version de production), ou de lister les objets base de données utilisés par les univers (études d'impacts de modification des bases de données).
Pour pallier ce manque, il est possible d'utiliser le SDK de Designer.
Pour rappel, une définition de SDK (Software Developpement Kit) : kit de développement ou trousse de développement logiciel est un ensemble d'outils permettant aux développeurs de créer des applications de type défini (source wikipedia fr).
Business Objects met à disposition pour chacun des clients lourds (Desktop Intelligence, Designer) un modèle objet ou SDK. Nous étudierons dans ce document l'utilisation de ce SDK pour le module Designer avec l'interface de développement Excel + VBA.
La Version de BO concernée est XI R2, mais cela doit être transposable dans les versions plus récentes ou antérieures.
Nous étudierons deux applications concrètes d'utilisation du SDK :
- retro engineering d'univers, export vers Excel
À partir d'un univers existant (déposé sur le disque, pas sur le référentiel de BO), nous allons déverser les informations les plus importantes de cet univers dans un fichier Excel (code SQL de chaque objet, type d'objets indicateurs ou dimension, tables de la base de données utilisées). Cet export Excel permet de faire des analyses d'impact, de la documentation technique. On peut également déterminer les colonnes de tables qui ne sont pas utilisées dans des objets de l'univers, en croisant la liste du SQL de chaque objet et la liste des tables/colonnes déposées dans l'univers ;
- création d'univers BO automatique à partir d'un fichier Excel
Le fichier Excel contient la liste des classes et objets BO, les tables et colonnes des bases de données associées. Par un programme VBA nous allons générer automatiquement l'univers, ce qui présente un intérêt dans certains cas : Designer nomme automatiquement les classes et objets BO à partir de leurs noms en base de données, noms qui sont souvent inadaptés pour une utilisation par un utilisateur « métier ». Il faut alors renommer chaque objet, ce qui est très fastidieux quand il y en a une centaine. Avec VBA, on peut donc directement associer le bon nom fonctionnel (issu d'un document métier par exemple). On peut également associer à chaque objet BO une définition fonctionnelle (qui peut être issue de Power AMC ou d'un référentiel entreprise).
II. Description du modèle objet BO XI Designer▲
II-A. Documentation officielle du SDK Designer▲
Le Universe Designer SDK est décrit (classes, propriétés et méthodes) à l'adresse suivante :
http://devlibrary.businessobjects.com/BusinessObjectsXIR2/en/devsuite.htm
Et le diagramme du modèle objet :
Ces liens sont valides au 02/11/2009.
Tout ceci parait bien compliqué pour faire une « simple » retro engineering d'univers. Nous allons donc étudier par la suite les éléments clés du modèle objet de Designer pour arriver à nos fins.
II-B. Rappel de la fenêtre Designer▲
La fenêtre de l'application Designer a la configuration suivante :
Sur la partie gauche, on trouve les classes, et sous les classes, on peut trouver d'autres classes ou des objets. Les classes servent à ranger les objets de manière cohérente pour l'utilisateur final (comme des dossiers). Les objets sont les données manipulées par les utilisateurs (dimensions, indicateurs). À chaque objet on associe un équivalent SQL, le plus souvent un simple « mapping » d'une colonne d'une table d'une base de données. À droite, on retrouve l'ensemble des tables utilisées dans l'univers, ainsi que les jointures utilisées pour lier les tables. Les jointures peuvent être regroupées dans des contextes.
Les éléments que l'on trouve sur cette fenêtre vont être repris presque à l'identique dans le modèle objet ! (comme quoi ce n'est pas si compliqué)
- Les classes,
- Les objets et leurs propriétés (indicateur ou dimension, SQL associé.),
- Tables utilisées,
- Colonnes des tables utilisées,
- Jointures,
- Contextes.
II-C. Description simple du modèle objet Designer▲
Les manipulations suivantes sont possibles uniquement si Excel et BO XI Designer sont installés sur le poste.
Tout d'abord, ouvrir l'éditeur VBA intégré à Excel (Alt + F11). Puis insérer un module dans notre fenêtre VBA : menu « Insertion - Module ». Il faut enfin référencer la bibliothèque (dll) contenant le modèle objet (les objets, leurs propriétés et méthodes) de Designer via le menu « Outils - Références » :
Dans le code, on appellera les bibliothèques Designer avec l'instanciation de l'objet « univers BO » :
Dim objBO as New Designer.Application
Enfin, pour naviguer plus facilement dans les objets, leurs méthodes et propriétés, afficher l'explorateur d'objet (F2), et choisir Designer : en sélectionnant l'objet tables (qui est en fait une collection), nous remarquons que cet objet contient des propriétés (Item, Count) et des méthodes (Add.).
Cela est vrai pour tous les objets clés du SDK :
- la collection Classes contient tous les objets Classe ;
- la collection Objects contient tous les objets Object ;
- la collection Tables contient tous les objets Table ;
- la collection Columns contient tous les objets Column ;
- la collection Joins contient tous les objets Join ;
- la collection Contexts contient tous les objets Context.
II-C-1. Collection Tables▲
Pour le vocabulaire « objet » (objet, méthode, collection « Tables » surlignée ; elle représente l'ensemble des tables déposées dans l'univers.
La propriété Count de la collection Tables (propriétés, collections) vous trouverez des cours spécialisés, mais nous pouvons expliquer simplement les notions de base au travers de l'exemple ci-dessus.
À gauche de la fenêtre, nous trouvons les classes (une classe est la gestion de l'objet : sa création, l'affectation de ses propriétés, et ses fonctions ou méthodes), et à droite, les propriétés et méthodes.
- Sur la copie d'écran ci-dessus, nous voyons le nombre de tables de la base de données utilisées dans l'univers.
- La méthode Add nous permet (en passant le nom en paramètre) d'ajouter une table dans l'univers et l'on devine dès maintenant que l'on peut construire un univers dynamiquement !
En balayant la collection à l'aide de l'instruction For Each . Next, nous lirons chaque table utilisée dans l'univers, et cette instruction renvoie pas à pas un objet « Table », dont voici la classe ci-dessous :
Nous remarquons ici que l'élément Table de la collection Tables contient lui-même une collection Columns, ce qui est tout à fait logique !
II-C-2. Collection Columns▲
La collection Columns possède également la méthode Add (comme toutes les collections en fait).
Pour chaque colonne, nous trouvons des propriétés « classiques » comme Key (clé ou non), Name, etc.
II-C-3. Collection Classes▲
On retrouve ici le principe de la récursivité des « Classes » BO, qui sont des répertoires : un répertoire peut contenir des sous-répertoires, donc un objet Class peut contenir à son tour une collection Classes représentant ses sous-classes.
II-C-4. Collection Objects▲
Les propriétés d'un objet sont nombreuses. On retrouve en fait la multiplicité des options disponibles dans la fenêtre propriétés d'un objet. Une propriété importante est, car c'est l'aide en ligne de l'utilisateur, la description fonctionnelle de chaque objet. Il peut être utile de mettre à jour ces Description par code VBA, à partir d'un référentiel entreprise de documentation (Power AMC par exemple). De même, la propriété Name (le nom en clair de l'objet) peut être mise à jour massivement avec du code VBA, car par défaut, le Name d'un objet est le nom SQL du champ associé, ce qui n'est pas très pratique pour l'utilisateur !
III. Programme d'export d'univers BO vers Excel▲
Le code présenté dans cet exemple est du VBA pour Excel, mais écrit de manière la plus simple possible :
- pas de déclaration de variables mis à part les objets BO (VBA sait se débrouiller pour un code simple) ;
- peu d'objets Excel utilisés ;
- pas de gestion des erreurs.
Ce code est suffisamment documenté pour une compréhension générale.
Rappel indispensable sous l'éditeur VBA : F8 pour exécuter le programme en mode pas à pas, clic droit sur une variable et « ajouter un espion » pour connaître les valeurs des variables en cours d'exécution.
Sub
EXPORT_UNIVERS
(
)
'Initialisation de la feuille Liste_BO
Sheets
(
"liste_BO"
).Select
Cells.ClearContents
Cells
(
1
, 1
).Value
=
"classe"
Cells
(
1
, 2
).Value
=
"sous_classe"
Cells
(
1
, 3
).Value
=
"objet"
Cells
(
1
, 4
).Value
=
"SQL"
Cells
(
1
, 5
).Value
=
"type"
Cells
(
1
, 6
).Value
=
"qualification"
ligne =
2
'Ouvre Business Object et l'univers choisi
filtre =
"Univers (*.unv),*.unv"
nomFichier =
Application.GetOpenFilename
(
filtre)
If
nomFichier =
False
Then
GoTo
fin
End
If
Dim
objBO As
New
Designer.Application
objBO.Visible
=
True
On
Error
Resume
Next
objBO.Logon
""
, ""
, False
, enterprise
If
Err
.Description
<>
""
Then
MsgBox
(
"Anomalie de login Designer..."
)
Set
objBO =
Nothing
GoTo
fin
End
If
Set
UniversBO =
objBO.Universes.Open
(
nomFichier)
'On balaie les classes
'ATTENTION !! une profondeur de 2 niveaux (classe et sous-classe) est codée. Si plus de profondeur, adapter le code (ou utiliser des fonctions récursives)
For
Each
Classe In
UniversBO.Classes
nom_classe =
Classe.Name
nom_sous_classe =
""
For
Each
objet In
Classe.Objects
description_univers ligne, nom_classe, nom_sous_classe, objet
ligne =
ligne +
1
Next
For
Each
sous_classe In
Classe.Classes
nom_sous_classe =
sous_classe.Name
For
Each
objet In
sous_classe.Objects
description_univers ligne, nom_classe, nom_sous_classe, objet
ligne =
ligne +
1
Next
Next
Next
'On balaie les tables et colonnes des tables de l'univers pour en faire la liste
Sheets
(
"liste_table"
).Select
Cells.ClearContents
Cells
(
1
, 1
).Value
=
"table"
Cells
(
1
, 2
).Value
=
"colonne"
ligne =
2
UniversBO.RefreshStructure
For
Each
Table In
UniversBO.Tables
tablename =
Table.Name
For
Each
Column In
Table.Columns
Cells
(
ligne, 1
).Value
=
tablename
Cells
(
ligne, 2
).Value
=
Column.Name
ligne =
ligne +
1
Next
Next
'On balaie les jointures et contextes pour en faire la liste
Sheets
(
"liste_jointures"
).Select
Cells.ClearContents
Cells
(
1
, 1
).Value
=
"table source"
Cells
(
1
, 2
).Value
=
"table cible"
Cells
(
1
, 3
).Value
=
"expression"
ligne =
2
For
Each
Item In
UniversBO.Joins
Cells
(
ligne, 1
).Value
=
Item.FirstTable
Cells
(
ligne, 2
).Value
=
Item.SecondTable
Cells
(
ligne, 3
).Value
=
Item.Expression
ligne =
ligne +
1
Next
Set
UniversBO =
Nothing
Set
objBO =
Nothing
Beep
MsgBox
(
"L'export est terminé."
)
fin
:
End
Sub
_______________________________________________________________________
Function
description_univers
(
ligne, nom_classe, nom_sous_classe, objet)
Cells
(
ligne, 1
).Value
=
nom_classe
Cells
(
ligne, 2
).Value
=
nom_sous_classe
Cells
(
ligne, 3
).Value
=
objet.Name
Cells
(
ligne, 4
).Value
=
objet.Select
Select
Case
objet.Type
Case
dsDateObject '(3) date
Cells
(
ligne, 5
).Value
=
"date"
Case
dsNumericObject '(1) numérique
Cells
(
ligne, 5
).Value
=
"numerique"
Case
dsCharacterObject '(2) alphanum
Cells
(
ligne, 5
).Value
=
"alphanumérique"
Case
dsBlobObject '(4) texte long
Cells
(
ligne, 5
).Value
=
"texte"
Case
Else
Cells
(
ligne, 5
).Value
=
"inconnu"
End
Select
Select
Case
objet.Qualification
Case
dsDimensionObject '(1) dimension
Cells
(
ligne, 6
).Value
=
"dimension"
Case
dsDetailObject '(2) information
Cells
(
ligne, 6
).Value
=
"information"
Case
dsMeasureObject '(3) indicateur
Cells
(
ligne, 6
).Value
=
"indicateur"
Case
Else
Cells
(
ligne, 6
).Value
=
"inconnu"
End
Select
End
Function
IV. Programme de création automatique d'univers▲
Il ne faut pas espérer faire l'univers entièrement, il faudra bien sûr l'affiner par la suite. Ce programme permet toutefois d'initialiser un (ou plusieurs) univers à partir d'informations externes (dans notre cas une feuille Excel) et ainsi d'avoir les noms en clair, des définitions d'objets, etc.
Vous trouverez une vidéo d'exemple de création automatique d'univers ici :
http://excel-methode.blogspot.com/2009/08/creer-un-univers-business-objects.html
Sub
GENERATION_UNIVERS
(
)
'Ouvre Business Object et crée un univers vide
Dim
objBO As
New
Designer.Application
objBO.Visible
=
True
objBO.Logon
"logon"
, "password"
, False
, enterprise
Set
UniversBO =
objBO.Universes.Add
(
)
'ÉTAPE 1 : ON CRÉE TABLES ET COLONNES
Sheets
(
"tables"
).Select
ligne =
2
Do
While
Cells
(
ligne, 3
).Value
<>
""
'test ajout table
If
Cells
(
ligne -
1
, 3
).Value
<>
Cells
(
ligne, 3
).Value
Then
nom_table =
Cells
(
ligne, 3
).Value
Set
table1 =
UniversBO.Tables.Add
(
nom_table)
End
If
'ajout colonnes
nom_colonne =
Cells
(
ligne, 5
).Value
table1.Columns.Add
nom_colonne
'destruction objet table
If
Cells
(
ligne, 3
).Value
<>
Cells
(
ligne +
1
, 3
).Value
Then
Set
table1 =
Nothing
End
If
ligne =
ligne +
1
Loop
UniversBO.ArrangeTables
'ÉTAPE 2 : ON CRÉE CLASSES ET SOUS-CLASSES
Sheets
(
"tables"
).Select
ligne =
2
Do
While
Cells
(
ligne, 1
).Value
<>
""
'test ajout classe
If
Cells
(
ligne -
1
, 1
).Value
<>
Cells
(
ligne, 1
).Value
Then
nom_classe =
Cells
(
ligne, 1
).Value
Set
classe1 =
UniversBO.Classes.Add
(
nom_classe)
End
If
'test ajout sous-classe
nom_sous_classe =
Cells
(
ligne, 2
).Value
If
nom_sous_classe <>
""
Then
If
Cells
(
ligne -
1
, 2
).Value
<>
Cells
(
ligne, 2
).Value
Then
Set
sous_classe1 =
classe1.Classes.Add
(
nom_sous_classe)
End
If
End
If
'affectation de la colonne à la classe / sous-classe
nom_objet =
Cells
(
ligne, 6
).Value
If
nom_sous_classe =
""
Then
Set
Object1 =
classe1.Objects.Add
(
nom_objet)
Else
Set
Object1 =
sous_classe1.Objects.Add
(
nom_objet)
End
If
Object1.Select
=
Cells
(
ligne, 3
).Value
&
"."
&
Cells
(
ligne, 5
).Value
texte1 =
"Table : "
&
Cells
(
ligne, 3
).Value
&
_
". Colonne : "
&
Cells
(
ligne, 5
).Value
If
Cells
(
ligne, 8
).Value
<>
""
Then
texte1 =
texte1 &
". "
&
Cells
(
ligne, 8
).Value
End
If
Object1.Description
=
texte1
'affectation du type
'1 : numérique (dsNumericObject)
'2 : alphanumérique (dsCharacterObject)
'3 : date (dsDateObject)
'4 : texte long (dsBlobObject)
Object1.Type
=
2
format_source =
Cells
(
ligne, 9
).Value
mode_aggreg =
Cells
(
ligne, 10
).Value
If
format_source =
"DATE"
Then
Object1.Type
=
3
End
If
If
Left
(
format_source, 6
) =
"NUMBER"
Then
'Adapter selon la saisie Excel
Object1.Type
=
1
End
If
If
format_source =
"SMALLINT"
Then
'Adapter selon la saisie Excel
Object1.Type
=
1
End
If
If
format_source =
"INTEGER"
Then
'Adapter selon la saisie Excel
Object1.Type
=
1
End
If
If
mode_aggreg =
"somme"
Or
mode_aggreg =
"moyenne"
Then
Object1.Type
=
1
End
If
'Affectation de la qualification
'1 : dimension (dsDimensionObject)
'2 : information (dsDetailObject)
'3 : indicateur (dsMeasureObject)
type_source =
Cells
(
ligne, 7
).Value
If
type_source =
"dimension"
Then
Object1.Qualification
=
1
End
If
If
type_source =
"indicateur"
Then
Object1.Qualification
=
3
End
If
'Affectation de la fonction d'agrégation
'1 : Somme
'4 : Moyenne
aggregat =
Cells
(
ligne, 10
).Value
If
aggregat =
"somme"
Then
Object1.AggregateFunction
=
1
End
If
If
aggregat =
"moyenne"
Then
Object1.AggregateFunction
=
4
End
If
'destruction objet sous-classe
If
Cells
(
ligne, 2
).Value
<>
""
Then
If
Cells
(
ligne, 2
).Value
<>
Cells
(
ligne +
1
, 2
).Value
Then
Set
sous_classe1 =
Nothing
End
If
End
If
'destruction objet classe
If
Cells
(
ligne, 1
).Value
<>
Cells
(
ligne +
1
, 1
).Value
Then
Set
classe1 =
Nothing
End
If
ligne =
ligne +
1
Loop
'ÉTAPE 3 : ON AJOUTE LES JOINTURES
Sheets
(
"jointures"
).Select
ligne =
2
Do
While
Cells
(
ligne, 1
).Value
<>
""
jointure =
Cells
(
ligne, 3
).Value
UniversBO.Joins.Add
jointure
ligne =
ligne +
1
Loop
UniversBO.ArrangeTables
'ÉTAPE 4 : ON AJOUTE LES CONTEXTES
'Attention, on trie par contexte pour ne créer qu'une seule fois le contexte (sinon, erreur)
Sheets
(
"jointures"
).Select
ActiveSheet.UsedRange.Sort
Key1:=
Cells
(
1
, 4
)
ligne =
2
Do
While
Cells
(
ligne, 1
).Value
<>
""
jointure =
Cells
(
ligne, 3
).Value
contexte =
Cells
(
ligne, 4
).Value
'test ajout contexte
If
contexte <>
Cells
(
ligne -
1
, 4
).Value
Then
Set
Contexte1 =
UniversBO.Contexts.Add
(
contexte)
End
If
Contexte1.Joins.Add
jointure
'destruction objet contexte
If
contexte <>
Cells
(
ligne +
1
, 4
).Value
Then
Set
Contexte1 =
Nothing
End
If
ligne =
ligne +
1
Loop
UniversBO.ArrangeTables
UniversBO.LongName
=
"NOM LONG"
UniversBO.Description
=
"DESCRIPTION A SAISIR"
Set
UniversBO =
Nothing
Set
objBO =
Nothing
MsgBox
(
"ajouter la connexion, nommer l'univers et enregistrer"
)
End
Sub
V. Conclusion▲
Les exemples proposés dans ce tutoriel n'ont pas vocation à se substituer à l'expertise du logiciel BO Designer, mais toutefois, la manipulation du modèle objet BO Designer permet d'automatiser des tâches parfois pénibles sans l'outil (renommer les objets un par un avec des noms fonctionnels, analyses d'impacts).
Utiliser le SDK BO Designer est pour finir un excellent moyen de contourner un des problèmes récurrents avec la version XI, la non-accessibilité du référentiel BO.