IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

WGET dans macro VBA avec gestion du code retour


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur Débutant
    Inscrit en
    Avril 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Débutant

    Informations forums :
    Inscription : Avril 2017
    Messages : 3
    Par défaut WGET dans macro VBA avec gestion du code retour
    Bonjour,

    voici mon problème pour lequel j'ai besoin d'aide. Donc merci par avance à ceux qui pourront m'aider. Et désolé, je me rends compte que mon message est assez long à lire...

    Contexte :
    pour récupérer des données d'un service fournisseur interne à mon entreprise, je dois utiliser des web services et retravailler les données qu'ils me renvoient (formatage, agglomération, .. avec aussi d'autres données de fichiers excel), par le biais d'une macro Excel VBA.
    J'utilise pour cela l'utilitaire wget.exe, avec les paramétrages d'appel aux webs services, et récupère un fichier de données au format .xml, via vba, que j'importe ensuite dans excel.
    Cela fonctionne bien dans la macro, du moins lorsque le web service répond convenablement.

    Problème :
    Le problème c'est que ces webs services peuvent ne pas répondre, ou pas tout de suite (code http 500 notamment, assez fréquent, qui impose d'attendre une trentaine de secondes avant de réexécuter l'appel). Et dans ce cas ça plante (car le fichier de données ne contient pas de données mais un message d'erreur, qui n'est pas reconnu au moment de l'import excel).

    Objectif :
    Je veux donc pouvoir tester le code retour du web service juste après l'appel, afin d'orienter mon traitement vers un import excel, une gestion d'erreur ou un délai d'attente, du genre :
    - appel web service
    - si code retour = 200 => traitement normal
    - si code retour = 500 => attente, et relance au bout de 30 sec
    - si code retour autre => arrêt du traitement et gestion d'erreur et message d'erreur.

    Mais je n'arrive pas à le faire, et je n'ai pas trouvé de réponse malgré toutes mes recherches (nombreuses) dans les forums/FAQ et dans l'aide de wget ou de vba.
    Je dois être idiot …
    J'ai essayé d'intercepter le code http, avec l'instruction "%{http_code}" , mais ça ne fait que l'afficher sans l'écrire dans un fichier en sortie.
    J'ai essayé de récupérer la sortie stdout dans un fichier de données (.xml), et la sortie stderr dans un fichier de log (.txt), ce qui fonctionne, mais ce dernier ne contient que l'affichage qui apparaît à l'écran quand on lance manuellement via invite de commande windows, et pas le code retour.
    J'ai testé le Err.Number, mais il ne contient pas le code http du web service appelé.
    Quand le WS renvoie un code 500, j'ai dans le fichier de données (.xml) le message {"responseCode":500,"message":"Read timed out","trace":null}, qui fait planter l'instruction d'import. Il me faut donc pouvoir analyser ce code retour http avant l'import !

    Mon code VBA en cours de réalisation (extrait):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    ....
    'Initialisation des variables spécifiques à l'appel du Web Service (paramètres):
    Nom_Chemin_exe = "C:\Users\xxxxxxx\"  
    Nom_exe = "wget.exe"
    Nom_Option_1 = " --no-check-certificate "
     
    If W_ENV = "PROD" Then     ‘W_ENV  indique l’environnement sur lequel ça tourne,PROD, RECETTE, etc …  paramètre)
         Nom_Connexion_WS_Gaia = "--header=""X-API-Key:xxxxxxxxx"" --http-user=""xxxxx xxx"" --http-password=""xxxxxxx""  "
         Nom_Chemin_WS_Gaia = "https://portail3xxxxxxx/"
    Else
         Nom_Connexion_WS_Gaia = "--header=""X-API-Key:yyyyyyyyyyyyyy"" --http-user=""yyyyyyyy"" --http-password=""yyyyyyy""  "
         Nom_Chemin_WS_Gaia = "https://portail3.yyyyyyyyyyyyyyyy/"
    End If
     
    'Le Web Service appelé :
    Nom_WS_Gaia = "specialites/xml"
    '
    'Paramètre du fichier d'extraction en sortie (données .xml) :
    Nom_Option_2 = "  -P /gaia/file -O "
    Nom_Chemin_Fic_sortie = "C:\Users\xxxxxxx\" 'Nom_Chemin_exe    
    If W_ENV = "PROD" Then
       Nom_Fic_sortie = "Fic_xxxxx_specialites" & "_" & Dat_heure & ".xml"
    Else
       Nom_Fic_sortie = "Fic_xxxxx_specialites" & "_" & Dat_heure & "_" & W_ENV & ".xml"
    End If
    Nom_Option_3 = " -x"
     
    FILENAME = Nom_Chemin_Fic_sortie & Nom_Fic_sortie
     
    'Tous ces paramètres agglomérés dans la variable Command
    command = Nom_Chemin_exe & Nom_exe & Nom_Option_1 & Nom_Connexion_WS_Gaia & Nom_Chemin_WS_Gaia & Nom_WS_Gaia & Nom_Option_2 & FILENAME & Nom_Option_3
     
     
    'Appel du WS (instruction "Shell")
    Shell command, vbNormalFocus
     
    'TEST QUI NE FONCTIONNE PAS
    ‘Gestion des codes erreur possibles : 500 <=> Indisponibilité temporaire du WS. ==> Attendre 30' et retenter !  
    If Err.Number = 500 Then
       Nb_tentatives = 1
       While Err.Number <> 0 And Nb_tentatives <= 10
          Application.Wait (Now + TimeValue("0:00:30"))
          Shell command, vbNormalFocus
          Nb_tentatives = Nb_tentatives + 1
       Wend
    End If
     
    'Si au bout de 10 tentatives successives on a toujours une erreur, décrochage en Fin de Traitement en Anomalie.
    If Err.Number <> 0 Then
       GoTo errorHandler
    End If
     
     
    '3) Import des données extraites dans l'onglet Excel "Données .xml"
    'Import fichier .xml dans un onglet Excel
        Dim XM As XmlMap
     
        XLS_NewBook.XmlImport _
            url:=FILENAME, _
            ImportMap:=Nothing, _
            Overwrite:=True, _
            Destination:=Worksheets("Données .xml").Range("$a$1")
     
        'Définit le mappage qui vient d'être ajouté.
        Set XM = XLS_NewBook.XmlMaps(ThisWorkbook.XmlMaps.Count)
     
     
        MsgBox "Import terminé" & vbCrLf & _
            XM.RootElementName & vbCrLf & _
            XM.Name & vbCrLf & _
            XM.DataBinding.SourceUrl
    ...
    Remarques complémentaires :
    - le choix technique est imposé : Web Service, et macro vba dans excel pour simplicité de traitement des fichiers et données diverses
    - je ne peux pas installer de logiciel sur le PC pro
    - j'ai été développeur il y a bien longtemps, mais quasi exclusivement en grand système (cobol). Je me débrouille en vba (sans être un pro), et je n'ai pas ou pas beaucoup de capacité dans d'autres langages
    - le traitement doit être le plus simple possible, pour son écriture et sa maintenance future.

  2. #2
    Membre expérimenté
    Profil pro
    au repos
    Inscrit en
    Février 2013
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2013
    Messages : 161
    Par défaut
    Salut,
    au lieu d'utiliser wget, tu peux essayer d'utiliser l'objet MSXML2.XMLHTTP60 qui se trouve dans la référence microsoft xml v6.0
    menu Outils/Références de VBA :
    Nom : msxmlv6.PNG
Affichages : 815
Taille : 22,2 Ko
    voici un bout de code qui télécharge un fichier et qui fait 3 nouvelles tentatives si le status de retour n'est pas 200 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #If VBA7 Then
        Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
    #Else
        Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'For 32 Bit Systems
    #End If
     
    Sub DownloadFile(url As String, filePath As String)
    Dim oStream As Object
    Dim WinHttpReq As New MSXML2.XMLHTTP60
    Dim attempts As Integer
    attempts = 3
    On Error GoTo TryAgain
    TryAgain:
        attempts = attempts - 1
        Sleep (200)
        Err.Clear
        If attempts > 0 Then
          WinHttpReq.Open "GET", url, False
            WinHttpReq.setRequestHeader "Content-Type", "text/json"
            WinHttpReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
            WinHttpReq.setRequestHeader "User-Agent", "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"
     
            WinHttpReq.send
            If WinHttpReq.Status = 200 Then
                Set oStream = CreateObject("ADODB.Stream")
                oStream.Open
                oStream.Type = 1
                oStream.Write WinHttpReq.responseBody
                oStream.SaveToFile filePath, 2 ' 1 = no overwrite, 2 = overwrite
                Debug.Print "Fichier sauvegardé dans " & filePath
                oStream.Close
            Else
            Debug.Print "erreur " + CStr(WinHttpReq.Status)
            Sleep (10000)
            GoTo TryAgain
            End If
        End If
    End Sub
     
    Sub Test_Telechargement()
    DownloadFile "https://httpstat.us/200", "M:\test\reponse.txt"
    End Sub
    Le site https://httpstat.us est très pratique pour faire des tests en paramètre on met le status que l'on veut qu'il renvoie :
    par exemple pour une erreur 500 https:/httpstat.us/500

    Nullosse

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur Débutant
    Inscrit en
    Avril 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Débutant

    Informations forums :
    Inscription : Avril 2017
    Messages : 3
    Par défaut
    Bonjour Nullosse ,

    tout d'abord, désolé de ma réponse tardive. Je ne m'étais pas reconnecté, et ensuite il m'a fallu me dépatouiller avec tes éléments de réponse.

    Ensuite, je tiens à te remercier grandement car non seulement ta réponse m'a permis de résoudre mon problème, mais j'ai appris beaucoup en l'analysant, en l'adaptant à mon code et en fouillant les forums !!
    Au final, j'ai donc suivi tes conseils et remplacé l'utilisation de Wget.exe par la méthode "MSXML2.XMLHTTP60", qui permet de tester le code retour comme on veut, qui est plus simple à mettre en oeuvre et qui me paraît plus efficace que Wget.exe (temps de réponse). Ca fonctionne nickel !

    Par contre, l'appel à https:/httpstat.us/500 (ou avec autre valeur de code) ne fonctionne pas dans la macro VBA.
    Ca fonctionne dans le navigateur, mais pas avec ce code embarqué en VBA (erreur système sur la ligne XmlHTTP.Open "GET", myurl, False où myurl = "https:/httpstat.us/500").
    J'ai testé autrement, en simulant le code retour par une variable, mais si tu as une solution sur ce problème, je suis preneur (histoire d'être rigoureux dans mes tests).

    Merci encore à toi !

    Et à bientôt sur le forum.

    Kefran

  4. #4
    Membre expérimenté
    Profil pro
    au repos
    Inscrit en
    Février 2013
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2013
    Messages : 161
    Par défaut
    Salut,
    Citation Envoyé par Kefran222 Voir le message
    Par contre, l'appel à https:/httpstat.us/500 (ou avec autre valeur de code) ne fonctionne pas dans la macro VBA.
    Ca fonctionne dans le navigateur, mais pas avec ce code embarqué en VBA (erreur système sur la ligne XmlHTTP.Open "GET", myurl, False où myurl = "https:/httpstat.us/500").
    avec le code publié ici chez moi avec Excel 2010 et windows 10 , je n'ai pas d'erreur. Et c'est bizarre on fait la requête internet plus tard que sur cette ligne. Peux-tu nous montrer le code exact que tu utilises parce que le nom de ta variable xmlHTTP me semble louche.

    Nullosse

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur Débutant
    Inscrit en
    Avril 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Débutant

    Informations forums :
    Inscription : Avril 2017
    Messages : 3
    Par défaut
    Salut à toi,
    j'ai également excel 2010 et windows10.
    Mon code, en résumé, est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    1) Déclaration des variables 
    Dim XmlHTTP As New MSXML2.XMLHTTP60     'Objet VBA pour télécharger un fichier xml depuis internet
    Dim W_URL As String                     'Variable contenant l'URL complète du WS 
    Dim W_User As String                    'Variable contanant le COMPTE de connexion au service XXX
    Dim W_Psw As String                     'Variable contenant le MOT DE PASSE de connexion au service XXX
    Dim W_APIKEY As String                  'Variable contenant l'API KEY de connexion au service XXX
    Dim W_WS As String                 'Variable contenant le NOM du WS à appeler
     
    ‘2) Valorisation des paramètres d’appel au Web Service :
        W_WS = "nom_web_service/xml"     '(/xml est dans le nom du web service)
         W_User = "SXXXXXXXX"
         W_Psw = "3tttttttttt"
         W_APIKEY = "ebe1d164-xxx-xxx-xxxxxxx"
    W_URL = https://xxxxxxxxxxxxxxxxxxxxxxx/ & W_WS
     
    ‘3) Appel du WS :
    '==> Méthode utilisée (GET), URL du WS, option synchrone/asynchr. (false = synchrone) et paramètres d'authentification
    XmlHTTP.Open "GET", W_URL, False, W_User, W_Psw
    '==> l'API KEY :
    XmlHTTP.setRequestHeader "X-API-Key", W_APIKEY
    '==> Envoi de la requête :
    XmlHTTP.send
     
    If XmlHTTP.Status = 200 Then   …..mon traitement, qui utilise XmlHTTP.responseBody
     
    ‘4) Récupération des données dans un fichier
    Dim fic As Integer                      'Variable pour le fichier à créer fichier
    Dim buffer() As Byte                    'Variable pour créer un buffer qui contient toutes les données extraites, en binaire, par le WS
     
       fic = FreeFile
       Open C/MonChemin /MonFichier.xml For Binary As #fic
       buffer = XmlHTTP.responseBody
       Put #fic, , buffer
       Erase buffer
       Close #fic
    Pour simuler le code retour HTTP pour mes tests, j'ai simplement remplacé l'alimentation de ma variable
    W_URL = https://xxxxxxxxxxxxxxxxxxxxxxx/ & W_WS
    par
    W_URL = https:/httpstat.us/500

    ce qui provoque l'erreur
    Erreur d’exécution ‘-2147012890 (80072ee6)’ :
    Erreur système : -2147012890

    avec positionnement sur la ligne de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    XmlHTTP.Open "GET", myurl, False, myuser, mypsw
    Je me suis dit que c'était peut-être dù aux variables compte et mot de passe, mais en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    XmlHTTP.Open "GET", myurl, False
    à la place, mais même résultat (même erreur d'exécution).

    Cela dit, en effectuant mes tests, je suis tombé sur un "vrai" cas de code HTTP=500, et j'ai pu valider mon algorithme.
    Mais comprendre la raison des erreurs m’intéresse, ne serait-ce par curiosité.

    Kefran

  6. #6
    Membre expérimenté
    Profil pro
    au repos
    Inscrit en
    Février 2013
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2013
    Messages : 161
    Par défaut
    Salut,
    bon j'ai eu du mal à trouver pourquoi cela ne fonctionnait pas chez toi, mais j'ai fini par trouver
    Tu as mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    W_URL = "https:/httpstat.us/500"
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    W_URL = "https://httpstat.us/500"
    mais c'est de ma faute j'avais fait une erreur de frappe dans mon message #2

    PS : Ne pas oublier de mettre la discussion en Résolu si cela est le cas.

    Nullosse

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/01/2017, 21h32
  2. [XL-2010] Pblm code sur fichier dans macro VBA
    Par Anna_2013 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 11/06/2013, 00h53
  3. Boucle dans macro SAS avec BY
    Par fafabzh6 dans le forum Macro
    Réponses: 5
    Dernier message: 17/06/2008, 12h08
  4. lire un fichier copié dans un dossier avec le meme code
    Par vieri31 dans le forum C++Builder
    Réponses: 22
    Dernier message: 27/05/2008, 03h23
  5. [VBA-E] Problème de tableau dans macro VBA
    Par Chouls dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 12/06/2006, 15h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo