API REST JSON depuis Excel et VBA

Consommer une API REST en JSON depuix Excel en VBA.

API REST JSON depuis Excel et VBA

Depuis plusieurs mois/années les développements d'applications sont découpées et offres de plus en plus d'APIs.
Le standard de facto est aujourd'hui l'API en REST / JSON, un monde sans état.

Macro Excel VBA-Web

Il existe une macro VBA disponible sur github qui permet facilement d'appeler une API Rest / Json.
Je l'ai utilisée par exemple pour extraire automatiquement l'ensemble des issues d'un repo GitLab mais nous allons l'utiliser ici avec un autre service.

Exemple pour les pressés

Pour note exemple, nous allons interroger des données de Pays disponible sur restcountries.eu.
Voici ci-dessous le code de démo. L'URL sera bien évidemment construite avec les bons paramètres.

Public Sub InterrogationPays()
    Dim Url As String
    Dim dataFromResponse As Collection
    
    Dim Client As New WebClient
    Dim Request As New WebRequest
    Dim Response As New WebResponse
    
    EnableLogging = True
    
    Client.BaseUrl = "https://restcountries.eu/rest/v2/name/fra"
    
    Set Response = Client.Execute(Request)
    
    If (Response.StatusCode = Ok) Then
        Set dataFromResponse = Response.Data
        ProcessResponse dataFromResponse
    End If
End Sub

Private Sub ProcessResponse(dataResponse As Collection)
    Dim ws As Worksheet
    Dim dataItem As Object
    Dim i As Integer
    Set ws = ActiveWorkbook.Worksheets(1)
    
    ws.Range("A1").Value = Now
    i = 0
    For Each dataItem In dataResponse
        ws.Range("B2").Offset(i).Value = dataItem.Item("name")
        ws.Range("C2").Offset(i).Value = dataItem.Item("capital")
        ws.Range("D2").Offset(i).Value = dataItem.Item("population")
        i = i + 1
    Next
End Sub

et nous obtenons:
VbaWeb-Macro02

Utilisation

Il suffit de télécharger les modules depuis le repo github.
Dézipper le contenu et vous pouvez utiliser directement la version VBA-Web - Blank.xlsm. Il s'agit d'un fichier vide (comme son nom l'indique) qui a les modules nécessaires déjà chargés.

Ouvrez le fichier Excel et allez dans l'éditeur Visual Basic et vous devez voir l'ensemble des classes disponibles.
VbaWeb-Macro01

La documentation est très fournie.

Son utilisation est classique:

  • vous commencez par définir votre point d'entrée à l'API, c'est à dire l'URL que vous pouvez construire dynamiquement avec une base qui varie peu et un chemin qui peut evoluer avec différentes versions d'APIs et enfin des paramètres.
  • vous pouvez définir d'autres paramètres à votre requete (comme les éléments du header)
  • vous executez votre requete qui vous retourne (normalement) une instance de Response qui vous reste ensuite à processer.

L'outil vous met à disposition un grand nombre d'aides qui facilitent les types de requetes les plus courantes comme un Get ou PostJSON, les objets Headers...

Mise à jour - Février 2019

Suite aux commentaires, je vais essayer de clarifier la gestion de la réponse JSon.

L'API retourne un objet simple:

Dans ce premier exemple, quand on interroge notre API, elle retourne un objet simple, c'est à dire commençant par "{".
simpleObj01

Dans ce cas, notre objet response doit être de type Dictionary, comme ci-dessous:

Sub sampleObj()
    Dim client As New WebClient
    Dim request As New WebRequest
    Dim response As New WebResponse
    
    Dim responseData As Dictionary
            
    EnableLogging = True
    
    client.BaseUrl = "http://localhost:8080/obj"
    Set response = client.Execute(request)
    
    If (response.StatusCode = Ok) Then
        Set responseData = response.Data
        Debug.Print "Name: " & responseData("Name")
    End If
End Sub

ce qui nous donne
simpleObj02

et maintenant, si on utilise une Collection pour notre responseData, nous avons le problème d'imcompatibilité de type, erreur 13: il n'arrive pas à transformer votre objet unitaire en une liste d'objets. D'où l'incompatibilité de type.
simpleObj03

L'API retourne un tableau d'objets:

Vous devez vous en douter si vous avez bien suivi, dans ce cas notre responseData doit être de type Collection.

array01

et voilà l'exemple pour récuperer le premier élement de notre liste d'objets. A noter que cette fois, il faut prendre le Item X de votre liste puis le champ voulu.

Sub sampleObj()
    Dim client As New WebClient
    Dim request As New WebRequest
    Dim response As New WebResponse
    
    Dim responseData As Collection
            
    EnableLogging = True
    
    client.BaseUrl = "http://localhost:8080/array"
    Set response = client.Execute(request)
    
    If (response.StatusCode = Ok) Then
        Set responseData = response.Data
        Debug.Print "Name: " & responseData.Item(1)("Name")
    End If
End Sub

et on obtient
array02

Si vous typé votre responseData en Dictionary, vous obtenez une erreur 13 d'incompataiblité de type.
array03

Et pour les structures plus complexe, vous mixez ces 2 types.

Et pout être sûr,

vous mettez un point d'arrêt au niveau du retour du serveur (par exemple sur le test du status retourné) et vous regardez dans la fenêtre des espions le type de response.Data.

update01-1