ASP.Net : Accédez à vos WebServices .Net depuis Office
|
Article Rédigé pour |
 |
23/10/2003
Par
Elise Dupont
niveau : intermédiaire
durée : de 30 à 60 minutes
Version PDF à télécharger (1.8 Mo)
Configuration requise : IIS, Office XP ou 2003, Office Web Services Toolkit pour XP ou 2003 selon votre version d'Office
Code Source Exemple
Microsoft Office XP Web Services Toolkit 2.0
Microsoft Office 2003 Web Services Toolkit 2.01
Droit de diffusion:
L'ensemble ou partie de ce document ainsi que le code mis à disposition, ne peut être diffusé sur d'autres sites Web sans l'autorisation au préalable de son créateur.
Avant Propos :
Depuis la version XP d'Office, Microsoft mets à votre disposition un outil, qui s'appelle Office Web Services Toolkit, et qui vous permet d'appeler des WebServices de façon très simplifiée. Ainsi, vous pouvez récupérer ou envoyer des données à vos WebServices, et exploiter le résultat dans la suite Office. En effet le Toolkit fournit des outils qui simplifient beaucoup le travail, en générant des classes, qu'il vous suffira d'utiliser dans votre code VBA.
Cet article vous explique pas à pas comment accéder à un WebService depuis Office (en VBA), mais se limitera a certains domaines : Je présente ici un exemple avec un WebService .Net, et j'ai choisit d'utiliser Excel pour illustrer la partie Office, mais cela aurait très bien pu être Word ou un autre produit de la suite Office.
Je vous conseille vivement de télécharger la Démo avec Code Source, afin d'installer le WebService sur votre Serveur IIS, et de tester avec le fichier Excel l'appel au WebService.
Curieux de savoir en détail ce que cela va donner ? C’est partit !
Sommaire:
1. Préparer la machine
2. Installer et tester le Webservice
3. Générer les références au WebService et les classes VBA grâce au Toolkit
4. Tester une première méthode
5. Et avec des types de retour plus complexes ?
5.1. Une structure
5.2. Un tableau de structures
5.3. Un DataSet
6. Limitations
1. Préparer la machine
2. Installer et tester le Webservice
Télécharger le
Code Source Exemple. Il s'agit d'un zip qui contient 2 zips : un pour le WebService, et un pour le fichier Excel, que vous utiliserons plus tard. Pour le moment, on s'occupe d'installer l'application Asp.Net sur IIS et de vérifier que le WebService fonctionne.
Dé-zippez le contenu du fichier WebService.zip dans un répertoire de votre choix
Ouvrez le Computer Management
Créez un Virtual Directory « WS4OfficeTests » et mappez le chemin vers le répertoire ou vous avez dézipé les fichiers du WebService.zip
Vérifiez que le WebService fonctionne en ouvrant dans IE
http://localhost/WS4OfficeTests/myWS.asmx. Vous devez obtenir ceci :
"WS4OfficeTests"
est le nom de l'application Asp.Net qui contient notre WebService
"MyWebService"
qui lui même contient plusieurs WebMéthodes :
GetString, GetInteger, GetDouble, GetSimpleStructure, GetComplexStructure et GetDataset.
Si vous observez, vous verrez que j'ai crée 6 méthodes, chacune renvoie un type de donnée différent, afin de pouvoir tester le comportement d'Office face à ces types. Nous allons donc tester une méthode qui retourne une chaîne, en entier, un flottant, une structure simple, un tableau de structures complexes, et enfin un Dataset. Vous pouvez faire vos propres WebMéthodes, à condition que le type de retour soit
Sérialisable.
3. Générer les références au WebService et les classes VBA grâce au Toolkit
Maintenant, on va pouvoir travailler depuis Office. La première étape est d'utiliser le
WebServices Toolkit afin de générer une Web-référence vers notre Web Service.
Ouvrez Excel et lancez l'éditeur VB en allant dans le Menu "Outils>Macros>Editeur VB" comme illustré sur la capture d'écran qui suit
Ajoutez une référence à notre WebService
« MyWebService ». Pour ce faire, dans l'éditeur VB allez dans le Menu "Outils>WebServices Reference" comme le montre l'image suivante
Une fenêtre s'ouvre. Cochez l'option "WebService URL" et donnez l'url vers notre WebService (en l'occurrence http://localhost/WS4OfficeTests/myWS.asmx). Appuyez sur le bouton Search
Office va chercher notre Webservice, et charger dans la liste à droite le contenu du WebService avec toutes les WebMéthodes qu'il a trouvé. Cochez le WebService nommé
"MyWebService"
Cliquez sur Add et laissez Office travailler. En fonction du nombre de WebMéthodes que contient le WebService, et des types de retour, cela prendra un certain nombre de secondes.
Observez dans votre éditeur VB le résultat : le Toolkit a généré un certain nombre de Classes, en se basant sur le WSDL. Regardons ça plus en détail :
Le module
clsof_Factory_myWebService est une classe qui intervient lors de la sérialisation/désérialisation du XML. Elle est notamment utilisée pour la WebMéthode qui renvoie un Dataset.
Le module
clsws_myWebService est une représentation en VBA du WebService : son nom, son URL, ses méthodes, ses types de retour.
Si nous n'avions utilisé comme type de retour que des types "simples" comme des Chaines et des Entiers, on n'aurait que 2 modules. Or vous pouvez constater que nous avons aussi 2 autres modules :
struct_ComplexStructure
et
struct_SimpleStructure. Le toolkit à généré des classes dont il a besoin pour comprendre le type de retour des méthodes
GetComplexStructure
et
GetSimpleStructure.
Voila, nous avons tous les éléments nécessaires : des classes qui représentent le WebService, et d'autres pour nos données plus complexes tels les Structures, Tableaux de Structures et Datasets.
4. Tester une première méthode
Nous allons maintenant faire notre application Excel. Elle sera très simple : une feuille pour l'appel aux WebMéthodes grâce à un bouton, et une feuille qui retourne les résultats de nos appels aux WebMéthodes. Ils nous faut donc d'abord ajouter un bouton a notre feuille Excel. Nous allons ici tester une WebMéthode très simple pour commencer :
GetString, qui retourne une chaîne "Hello World"
Ouvrir le Menu "View>Toolbars>Forms"
Une fenêtre avec quelques contrôles VB apparaît. On va sélectionner le controle de type Bouton et en dessiner un sur notre feuille Excel.
Donnez lui un nom explicite, et changez aussi le texte qui apparaît sur le bouton. Pour ce faire cliquez-droit sur le bouton et sélectionnez "Properties". Une fenêtre Properties apparait.
Maintenant on va créer le code VBA. Double cliquez sur le bouton que vous venez de créer. Vous allez vous retrouver dans l'éditeur VB, sur l'évènement Click de votre bouton. Il vous suffit d'appeler une Méthode
"GetString" que nous allons créer juste après. Ici il s'agit de syntaxe VBA :
Code VBA
Private
Sub
btnGetString_Click
()
Call
GetString
End
Sub
|
Nous allons créer un module commun, qui contiendra la déclaration de notre Objet de type
clsws_myWebService et les méthodes qui appellent les WebMéthodes. Cliquez-droit sur votre VBAProjet et sélectionnez "Insert > Module"
Un module nommé Module1 apparaît à gauche. Double cliquez dessus pour l'ouvrir.
Déclarez votre WebService :
Code VBA
Option
Explicit
'Déclarer un objet de type clsws_myWebService, qui est une référence au web service que l'on a crée
Public
Monwebservice
As
New
clsws_myWebService
|
Créons notre Méthode
"GetString" :
Déclarez une String, et ensuite utilisez notre objet
Monwebservice. Lorsque vous tapez le code
"résultat = Monwebservice." un menu apparaît avec toutes les WebMéthodes disponibles pour le WebService.
Le reste du code est simple et compréhensible je pense :
Code VBA
Public
Function
GetString
()
'Définir variable de retour - ici c'est une String
Dim
res
As
String
res
=
Monwebservice.wsm_GetString
()
'Afficher le résultat dans la deuxieme feuille
Sheets
(
2
).
Cells
(
4
,
3
).
Value
=
res
'Afficher la feuille résultats
Sheets
(
2
).
Select
End
Function
|
Voila c'est prêt à être testé ! Pour tester il faut quitter le mode Edition (le mode qui nous a permit de créer le bouton et de double cliquer sur le bouton) :
Ouvrir le Menu "View > Toolbars > Visual Basic"
Cliquer sur l'icône
"Exit Design Mode". C'est ce bouton qui va nous permettre de passer du mode design au mode normal. A chaque fois que vous voudrez modifier votre bouton il faudra repasser en mode Design, et a chaque fois que vous voudrez tester quittez le mode Design.
Cliquez sur le bouton que vous avons crée et observez le résultat : l'appel au WebService est fait et prend quelques secondes la première fois. Une fois le premier appel fait, les autres seront beaucoup plus rapides. L'appel à la WebMéthode GetString retourne la chaine "Hello World"
C'est facile non ? Normal, tout ce qu'on a fait c'est appeler une méthode qui renvoie une chaîne. On peut aussi tester ainsi les méthodes simples comme GetInteger et GetDouble. Mais avec des types plus complexes, comment se comporte Office ? C'est ce que nous allons voir tout de suite dans le prochain paragraphe.
5. Et avec des types de retour plus complexes ?
Nous allons tester dans l'ordre les méthodes : GetSimpleStructure, GetComplexStructure et GetDataset. Là où nous déclarions des variables de type String, Integer ou Double, à la place il va falloir adapter les variables de retour aux limitations de VBA. Cette partie du tutoriel est la pour vous donner des éléments afin de chercher une façon d'adapter votre VBA à des WebServices plus complexes que "Hello World", car dans la vrai vie, les applications retournent rarement "Hello World" ;-)
5.1. Une structure
Notre WebMéthode
GetSimpleStructure
retourne en fait une classe de type
SimpleStructure, que nous avons définie dans .Net, et qui est décrite dans le WSDL de notre WebService. Voici la structure coté .Net :
Code coté WebService .Net
1: <Serializable()> Public Class SimpleStruture
2: Private m_nInt As Integer 'un Entier
3: Private m_strString As String 'une Chaine
4: Private m_oDate As Date 'une Date
5: Private m_oRecord_Status As Record_Status 'une Enumeration : au choix Actif/PasActif
6:
7: Public Sub New()
8: End Sub
9: End Class
|
Mais quel type utiliser dans Excel ? Voici la méthode à suivre :
Commencez votre fonction VBA comme les précédentes, mais laissez de coté la déclaration de la variable résultat. Tapez simplement :
Code VBA
|
Set
res
=
Monwebservice.wsm_GetSimpleStructure
|
Pour savoir quel type retourne la Méthode wsm_GetSimpleStructure, cliquez-droit dessus et sélectionnez "Définition"
Cela vous emmène vers le code qui a été généré au tout début. Si vous observez la déclaration de la Web Méthode
wsm_GetSimpleStructure, vous constatez qu'elle retourne une variable de type
struct_SimpleStruture
C'est en fait un type qui a été définit et généré par le Toolkit. Tout le travail est mâché ! Il vous suffit de définir une variable de retour de type
struct_SimpleStruture. Ensuite pour manipuler le résultat, tout est intuitif : la liste des éléments de la structure apparaît dans un menu contextuel dès que vous tapez le texte "monRésultat."
Et voici donc le code final pour une structure simple :
Code VBA
Public
Function
GetSimpleStruct
()
'Définir variable de retour - Ici c'est une structure simple, de type struct_SimpleStruture, qui comporte des éléments de type entier, date et chaine
Dim
res
As
New
struct_SimpleStruture
Set
res
=
Monwebservice.wsm_GetSimpleStructure
'Afficher le resultat dans la deuxieme feuille
Sheets
(
2
).
Cells
(
7
,
3
).
Value
=
"ID: "
&
res.nInt
&
" - Date:"
&
res.oDate
&
" - Status:"
&
res.oRecord_Status
&
" - Msg:"
&
res.strString
'Afficher la feuille résultats
Sheets
(
2
).
Select
End
Function
|
5.2. Un tableau de structures
Voici la structure coté WebService . Net :
Code coté WebService .Net
1: <Serializable()> Public Class ComplexStructure
2: Private m_oSimpleStrutures As SimpleStruture() 'Un tableau de structures simples
3: Private m_oCategories As Category 'Une Enumeration : au choix Animals/Objects/Humans/Other
4:
5: Public Sub New()
6: End Sub
7: End Class
8: 'Il s'agit d'une ComplexStucture mais le WebService renvoit un tableau de ces objets donc le code de la WebMéthode :
9: <WebMethod()> Public Function GetComplexStructure() As DataStructures.ComplexStructure()
10: 'Retourne un Tableau de Structures complexes, lui meme composé de tableaux de structures simples
11: Return FillmyData.GiveMeaComplexStructure()
12: End Function
|
Pour le tableau de structure c'est un peu moins intuitif. En effet, Office va "traduire" le Tableau de structures définit dans le WSDL par un type de donnée très générique :
Variant. On peut "naviguer" dedans, mais il faudra chercher un peu. Voici comment procéder :
Définir une variable "résultat" en tant que Variant
Définir une autre variable de type Variant
Faire une boucle For Each de la façon suivante :
Code VBA
For
Each
item
In
res
Sheets
(
2
).
Cells
(
i
,
3
).
Value
=
item
Next
|
Pour savoir "de quoi est fait" le
Variant, on va exécuter le code, qui va pour le moment retourner une erreur. Lors de l'erreur, cliquez sur "Debug". On va observer le contenu de l'objet "item" afin de le décortiquer et de savoir comment le manipuler. Dans le code VBA cliquez-droit sur item et sélectionnez "Add to watch". Ajoutez un point d'arrêt sur la ligne
"Sheets(2).Cells(i, 3).Value = item" et testez le code. Le contenu de la variable d'affichera dans la fenêtre "Watch".
Déployez l'arbre. Vous avez maintenant une piste pour le code. Pour la Web méthode GetComplexStructure, le code VBA final est donc :
Code VBA
Public
Function
GetComplexStruct
()
'Définir variable de retour - Ici c'est un taleau de structures complexes,
'composées d'une chaîne qui définit le type, et d'une liste d'objets de type structure simple,
'Excel utilise donc le type Variant car il ne sait pas gérer des tableaux de structures de type monobjet(1).mastructure.monElement
Dim
res
As
Variant
Dim
item
As
Variant
Dim
subItem
As
Variant
res
=
Monwebservice.wsm_GetComplexStructure
'Afficher le résultat dans la deuxieme feuille
Dim
i
As
Integer
i
=
8
'Tester la valeur de retour du WebService avant de l'utiliser
If
Not
IsEmpty
(
res
)
Then
'Dans chaque membte du tableau de type variant
For
Each
item
In
res
'Afficher le type (humain, animal ...)
Sheets
(
2
).
Cells
(
i
,
3
).
Value
=
item.oCategories
&
" : "
'Parcourir chaque élément de type SimpleStructure
For
Each
subItem
In
item.oSimpleStrutures
'Afficher la chaine contenue dans chaque simples structures
Sheets
(
2
).
Cells
(
i
,
3
).
Value
=
Sheets
(
2
).
Cells
(
i
,
3
).
Value
&
subItem.strString
&
" - "
Next
'Incrémenter l'index qui fait changer de ligne à chaque type de structure differentes.
i
=
i
+
1
Next
End
If
'Afficher la feuille résultats
Sheets
(
2
).
Select
End
Function
|
5.3. Un DataSet
Pour le DataSet, on atteint un niveau de non-intruivité assez élevé. En effet, Office ne comprends pas du tout le Dataset comme un type simple tel que String ou meme Variant, et c'est donc un Objet XML que nous devrons manipuler. Le but de cet article n'étant pas de vous expliquer comment parser du XML sous VBA, je ne rentrerai pas dans les détails, mais voici quelques pistes :
Observons déjà ce que retourne le WebService lorsqu'on lui demande un DataSet : Dans votre navigateur, entrez l'URL du Web Service :
http://localhost/WS4OfficeTests/myWS.asmx. Cliquez sur le lien GetDataset, puis sur le bouton Invoke. Voici le Dataset tel qu'il est transmit, dans l'enveloppe SOAP, en XML donc :
Si l'on regarde dans Office les classes générées, on voit que la WebMethode retourne un objet de type
MSXML2.IXMLDOMNodeList.
Voici donc le type d'objet qu'il faudra manipuler. En observant avec la fenêtre Watch le contenu de cette variable voila ce que cela donne :
Il va falloir donc parser le XML pour pouvoir en sortir une donnée compréhensible. Je vous l'accorde, ce n'est pas une mince affaire. Heureusement, Office fournit des librairies pour manipuler ces objets. En fait vous devrez utiliser le
MSXml SDK.
Si vous lancez l'Excel fournit dans le zip FichierExcel.zip, et que vous testez l'application, vous devriez au final obtenir ceci :
6. Limitations
Comme vous avez pu le voir avec les Dataset, tous les types .Net ne sont pas facilement gérés dans Office. Ainsi cela commence à se corser dès que vous manipulez des tableaux d'objets, ou des Datasets.
Il vous faudra dont peut être adapter les types de retour de votre Webservice pour faciliter le traitement dans Office, ou alors si Office n'est pas le seul client à vos WebServices et que par exemple retourner des Datasets vous facilite vraiment la tache pour les autres clients .Net, et bien il vous faudra investir un peu de temps coté Office pour obtenir un traitement des données compréhensible par l'utilisateur.
A bien y réfléchir, c'est normal qu'Office ne comprenne pas de façon "native" les Dataset, il s'agit d'objets spécifiques au framework .Net. Mis à part les Dataset les autres types de données sont totalement exploitables avec un délais de développement assez rapide.
Bon code !
|