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 :

Résultat d'une requête Web à rapatrier dans un classeur Excel [XL-2010]


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut Résultat d'une requête Web à rapatrier dans un classeur Excel
    Bonjour à toutes et à tous,

    Je suis nouveau sur le forum et "pire", je débute un peu en VBA

    Je souhaite faire des requêtes sur un site web et récupérer une des données fournies.
    Après quelques jours (soirées et week-end), je bloque.

    J'ai puisé mon inspiration dans les articles déjà rédigés sur developpez.net, mais malgré cela, je n'arrive plus trop à me dépatouiller.
    d'où l'objet du présent post...

    Voici mon code qui fonctionne mais qui ne va pas aussi loin que je le voudrais.

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    Option Explicit
    Sub PremierIE()
    'Déclaration des variables
    Dim IE As New InternetExplorer
    Dim IEDoc As HTMLDocument
    Dim InputRatpOrigineZoneTexte As HTMLInputElement
    Dim htmlSelectElem As HTMLSelectElement
    Dim InputRatpDestinationZoneTexte As HTMLInputElement
    Dim InputDateDepartZoneTexte As HTMLInputButtonElement
    Dim InputTemps As HTMLGenericElement
    Dim InputRatpBouton As HTMLInputElement
     
       'Chargement d'une page web moteur de recherche RATP
       IE.Navigate "http://www.ratp.fr/itineraires/fr/ratp/recherche-avancee"
     
       'Affichage de la fenêtre IE
       IE.Visible = True
     
       'On attend le chargement complet de la page
       WaitIE IE
     
       'On pointe le membre Document
       Set IEDoc = IE.document
     
       'On pointe la première Zone de texte Origine
       Set InputRatpOrigineZoneTexte = IEDoc.all("itineraire[start]")
     
       'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
       'normalement le code est : InputRatpOrigineZoneTexte.Value = ActiveCell(2, 1) mais pour simplifier :
       InputRatpOrigineZoneTexte.Value = "15 Av. des Champs-Élysées 75008 Paris"
     
       'On pointe la seconde Zone de texte Destination
       Set InputRatpDestinationZoneTexte = IEDoc.all("itineraire[end]")
     
       'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
       'normalement le code est : InputRatpDestinationZoneTexte.Value = ActiveCell(2, 2) mais pour simplifier :
       InputRatpDestinationZoneTexte.Value = "69 Boulevard de la Villette 75010 Paris"
     
        'On pointe l'heure de départ
        Set htmlSelectElem = IEDoc.all("itineraire[time][hour]")
     
        'On écrit l'heure de départ 7h
        htmlSelectElem.Value = "7"
     
        'On pointe les minutes de départ : 25 par exemple
        Set htmlSelectElem = IEDoc.all("itineraire[time][minute]")
     
        'On écrit les minutes de départ 6h
        htmlSelectElem.Value = "25"
     
        'On pointe la date de départ le 25/11/2014 par exemple
        Set InputDateDepartZoneTexte = IEDoc.all("itineraire[date]")
     
        'On écrit la date de départ
        InputDateDepartZoneTexte.Value = "25/11/2014"
     
       'On pointe notre bouton
        Set InputRatpBouton = IEDoc.all("action_submit")
     
        'On simule un clic
        InputRatpBouton.Click
     
        'On attend la fin de la recherche
        WaitIE IE
     
        'On sélectionne la valeur dans la page web
        'Set ?? pas id, pas de name, balise dl, dt et dd
     
     
        'On copie la valeur sélectionnée
     
     
        'On colle la valeur dans la cellule à droite de la dernière cellule sélectionnée
        'ici la valeur recherchée est 31 min
     
       'On libère la variable IE  
       Set IE = Nothing
       Set IEDoc = Nothing
     
    End Sub
     
    Sub WaitIE(IE As InternetExplorer)
       'On boucle tant que la page n'est pas totalement chargée
       Do Until IE.readyState = READYSTATE_COMPLETE
          DoEvents
       Loop
    End Sub
    Ma difficulté vient du fait que le résultat soit contenu dans des balise dl, dd, dt

    et que je ne sais comment coller ce résultat dans la cellule du classeur.

    Après, je souhaiterai faire "tourner" le script car j'aurai plusieurs adresses d'origine (colonne A) vers plusieurs adresses de destination (colonne B) ; la colonne C étant réservé à la réception du temps de parcours.

    Je souhaite un coup de pouce ! Merci d'avance.

    _yuck_

  2. #2
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut heu
    Bonsoir

    Ma difficulté vient du fait que le résultat soit contenu dans des balise dl, dd, dt
    les éléments que l'on veut récupérer et qui n'ont pas de name,id etc...on les récupère par les nom des balises
    exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set elementsdt=Iedoc.getelementsbytagname("dt")'entre les parenthezes mettre le tag de la balise
    si il y en a plusieur
    pour lire la donnée on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    msgbox elementsdt(0).innertext'pour le premier ,1 pour le 2 eme et ainsi de suite
    sil il y en a qu'un se sera 0
    Voila
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #3
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Bonjour !

    Monsieur l'urbaniste, merci à l'avenir de respecter les règles du forum en balisant le code via l'icône dédiée !
    Ceci dit, pour un débutant vu le code présenté, c'est bien parti, félicitations !

    Consulter aussi cette discussion avec deux exercices dont un sur le site de la SNCF (après la RATP !) …

    Voici une démonstration passant des paramètres à la procédure affichant l'itinéraire et les lignes de métro :

    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
    Sub Demo()
        ItineraireRATP "15 Av. des Champs-Élysées 75008 Paris", _
                       "69 Boulevard de la Villette 75010 Paris", "7", "25", "25/11/2014"
    End Sub
     
     
    Sub ItineraireRATP(ParamArray PA())
        Const URL$ = "http://www.ratp.fr/itineraires/fr/ratp/recherche-avancee"
        If UBound(PA) < 4 Then Beep: Exit Sub
     
        With CreateObject("InternetExplorer.Application")
            .Navigate URL
            While .Busy Or .ReadyState < 4:  DoEvents:  Wend
     
            With .Document
                With .all
                          .itineraire_start.Value = PA(0)
                            .itineraire_end.Value = PA(1)
                      .itineraire_time_hour.Value = PA(2)
                    .itineraire_time_minute.Value = PA(3)
                           .itineraire_date.Value = PA(4)
                    .action_submit.Click
                End With
     
                While .ReadyState <> "complete":  DoEvents:  Wend
     
                T$ = "Du " & PA(0) & vbLf & "vers le " & PA(1) & vbLf & vbLf & _
                     Replace(Replace(.getElementsByTagName("DL")(0).innerText, "Zones :", _
                     "  Zones :"), "Arrivée :", vbLf & "Arrivée :") & " le " & PA(4)
     
                For Each vRow In .all.pivi.getElementsByTagName("TABLE")(1).Rows
                    For Each vElt In vRow.Cells(0).all
                          If vElt.className = "ligne" Then
                              T = T & vbLf & vbLf & vElt.alt & " : " & vbLf & _
                                  Replace(Replace(vRow.Cells(1).innerText, "direction ", _
                                  "  direction "), "jusqu", vbLf & "jusqu")
                          End If
                    Next
                Next
             End With
     
            .Quit
        End With
     
        MsgBox T, , "   " & Split(URL, "/")(2)
    End Sub
    Contrairement au tutoriel Manipulation d'Internet Explorer via VBA, ce code n'a pas besoin d'activer de référence
    car il utilise une liaison tardive, voir le tutoriel Les fiches VBA - Comprendre : Early ou Late Binding

    Cependant, durant la phase de développement, mieux vaut conserver les références
    afin de pouvoir visualiser le contenu de certaines variables objet dans la fenêtre des Variables locales.

    __________________________________________________________________________________________

    Merci de cliquer sur pour chaque message ayant aidé puis sur pour clore cette discussion …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  4. #4
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Merci bien pour toutes ces informations !
    Désolé pour le "non balisage" du code via l'icône dédiée, qu'hier soir, après minuit, je n'ai pas trouvée...

    Je vais me pencher sur les propositions dès ce soir.

    Par ailleurs, j'avais indiqué avoir utilisé le site pour m'inspirer.
    Il s'agissait du même article ! Interaction avec Internet Explorer via VBA Excel

    Promis, la prochaine fois, j'utilise la base ["CODE"] ["/CODE"]

    Merci encore !

  5. #5
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    joli boulot marc!!

    le parmarray en argument tip top

    il lui reste plus qu'a travailler la boucle sur le row de la table pour retranscrire dans le sheets
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  6. #6
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut




    Merci Patrick !

    Le besoin a l'air d'être bien plus simple s'il s'agit juste de récupérer le temps de parcours …

    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  7. #7
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par patricktoulon Voir le message
    Bonsoir



    les éléments que l'on veut récupérer et qui n'ont pas de name,id etc...on les récupère par les nom des balises
    exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set elementsdt=Iedoc.getelementsbytagname("dt")'entre les parenthezes mettre le tag de la balise
    si il y en a plusieur
    pour lire la donnée on fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    msgbox elementsdt(0).innertext'pour le premier ,1 pour le 2 eme et ainsi de suite
    sil il y en a qu'un se sera 0
    Voila
    J'ai eu beau essayé ça ne fonctionne pas

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    Option Explicit
    Sub PremierIE()
    'Déclaration des variables
    Dim IE As New InternetExplorer
    Dim IEDoc As HTMLDocument
    Dim InputRatpOrigineZoneTexte As HTMLInputElement
    Dim htmlSelectElem As HTMLSelectElement
    Dim InputRatpDestinationZoneTexte As HTMLInputElement
    Dim InputDateDepartZoneTexte As HTMLInputButtonElement
     
    Dim InputTemps As HTMLGenericElement
     
    Dim InputRatpBouton As HTMLInputElement
     
     
       'Chargement d'une page web moteur de recherche RATP
       IE.Navigate "http://www.ratp.fr/itineraires/fr/ratp/recherche-avancee"
     
       'Affichage de la fenêtre IE
       IE.Visible = True
     
       'On attend le chargement complet de la page
       WaitIE IE
     
       'On pointe le membre Document
       Set IEDoc = IE.document
     
       'On pointe la première Zone de texte Origine
       Set InputRatpOrigineZoneTexte = IEDoc.all("itineraire[start]")
     
       'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
        InputRatpOrigineZoneTexte.Value = ActiveCell(2, 1)
     
       'On pointe la seconde Zone de texte Destination
       Set InputRatpDestinationZoneTexte = IEDoc.all("itineraire[end]")
     
       'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
       InputRatpDestinationZoneTexte.Value = ActiveCell(2, 2)
     
        'On pointe l'heure de départ
        Set htmlSelectElem = IEDoc.all("itineraire[time][hour]")
     
        'On écrit l'heure de départ 7h
        htmlSelectElem.Value = "7"
     
        'On pointe les minutes de départ : 25 par exemple
        Set htmlSelectElem = IEDoc.all("itineraire[time][minute]")
     
        'On écrit les minutes de départ 6h
        htmlSelectElem.Value = "25"
     
        'On pointe la date de départ le 25/11/2014 par exemple
        Set InputDateDepartZoneTexte = IEDoc.all("itineraire[date]")
     
        'On écrit la date de départ
        InputDateDepartZoneTexte.Value = "25/11/2014"
     
       'On pointe notre bouton
        Set InputRatpBouton = IEDoc.all("action_submit")
     
        'On simule un clic
        InputRatpBouton.Click
     
        'On attend la fin de la recherche
        WaitIE IE
     
        'On sélectionne la valeur dans la page web
        Set InputTemps = IEDoc.getElementsByTagName("dt") 'entre les parenthèses mettre le tag de la balise
     
     
      'On le place dans notre variable prévue à cet effet
       MsgBox InputTemps(0).innerText
     
     
       'On libère la variable IE
       Set IE = Nothing
       Set IEDoc = Nothing
     
          'MsgBox
     
     
    End Sub
     
    Sub WaitIE(IE As InternetExplorer)
       'On boucle tant que la page n'est pas totalement chargée
       Do Until IE.readyState = READYSTATE_COMPLETE
          DoEvents
       Loop
    End Sub

    J'ai pourtant déclaré ma variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim InputTemps As HTMLGenericElement
    J'ai remplacé le "elementsdt" de patricktoulon par mon "InputTemps"

    mais ça bloque.

    le code HTML 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
    <div class="box switch-details">
          <div class="header"><span><!-- --></span></div>
          <dl class="clearfix">
      <dt>Départ&nbsp;:&nbsp;</dt>
        <dd>
          7<abbr title="heures">h</abbr>27  </dd>
      <dt>Durée totale&nbsp;:&nbsp;</dt>
      <dd>27&nbsp;<abbr title="minute">min</abbr></dd>
      <dt>Zones&nbsp;:&nbsp;</dt>
      <dd class="zones">1-2</dd>
      <dt>Arrivée&nbsp;:&nbsp;</dt>
      <dd class="last">
        7<abbr title="heures">h</abbr>54  </dd>
    </dl>

    Bref, j'ai relu et je ne comprends
    après, j'ai essayé avec ClassName="box switch-details"
    mais pas plus de résultats....

    Sinon, je chercherai un peu dans le post "SNCF" mais là, je vais faire un petit somme.

    Si la solution de Marc_L semble intéressante, je n'ai pas le niveau pour la maîtriser.
    Je préfère y aller de manière empirique... petit à petit.

    Bonne soirée/nuit

  8. #8
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Suite à mon précédent code, comme le site fonctionne avec seulement deux paramètres - les adresses -
    voici des démonstrations pour une fonction à paramètres variables (l'astuce consistant à faire correspondre
    la variable tableau des paramètres avec celle des éléments de la page web) extrayant le temps de trajet,
    la Demo1 affichant par exemple "31 min" et la Demo2 récupérant uniquement la valeur numérique :

    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
    Sub Demo1()
        MsgBox TempsRATP("15 Av. des Champs-Élysées 75008 Paris", _
                         "69 Boulevard de la Villette 75010 Paris", "7", "25", "25/11/2014")
    End Sub
     
    Sub Demo2()
        [C2].Value = Val(TempsRATP([A2].Value, [B2].Value))
    End Sub
     
     
    Function TempsRATP$(ParamArray PA())
        If UBound(PA) < 1 Then TempsRATP = "Erreur!": Exit Function
        AR = Array("start", "end", "time_hour", "time_minute", "date")
     
        With CreateObject("InternetExplorer.Application")
            .Navigate "http://www.ratp.fr/itineraires/fr/ratp/recherche-avancee"
            While .Busy Or .ReadyState < 4:  DoEvents:  Wend
     
            With .Document
                With .all
                    For N% = 0 To Application.Min(UBound(AR), UBound(PA))
                        .Item("itineraire_" & AR(N)).Value = PA(N)
                    Next
     
                    .action_submit.Click
                End With
     
                While .ReadyState <> "complete":  DoEvents:  Wend
                TempsRATP = .getElementsByTagName("DL")(0).all(4).innerText
            End With
     
            .Quit
        End With
    End Function
    Ce code est la résultante du tutoriel et de l'analyse de la page web via son code et l'outil d'inspection
    de tout navigateur Web (F12), en visualisant le contenu d'une variable pointant sur la collection des éléments "DL",
    la donnée se trouvant dans le premier élément de cette collection dans son cinquième sous-élément … (ligne n°29)


    Or, en observant l'adresse de la page du résultat de la recherche, il est inutile de procéder ainsi ‼
    Et oui car dans cette adresse il y a les paramètres de la recherche :
    inutile donc de passer par la première page afin d'y renseigner les paramètres,
    autant appeler directement la page résultat, gagnant ainsi deux bonnes secondes de traitement !

    Voici donc une nouvelle fonction nécessitant seulement quatre paramètres : les deux premiers - les adresses - sont obligatoires
    puis suivent la date et l'heure, respect de l'ordre dans l'adresse de la page résultat …
    Mais tous les paramètres étant obligatoires dans cette adresse, le code se charge de fournir si besoin la date et l'heure :

    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
    Sub Demo1()
        MsgBox TempsRATP("15 Av. des Champs-Élysées 75008 Paris", _
                         "69 Boulevard de la Villette 75010 Paris", "25/11/2014", "7:25")
    End Sub
     
    Sub Demo2()
        [C2].Value = Val(TempsRATP([A2].Value, [B2].Value))
    End Sub
     
     
    Function TempsRATP$(ParamArray AR())
        Dim PA()
        If UBound(AR) < 1 Then TempsRATP = "Erreur!": Exit Function
        PA = AR:  If UBound(PA) < 3 Then ReDim Preserve PA(3)
        If Not IsDate(PA(3)) Then PA(3) = "8:0"
     
        If IsDate(PA(2)) Then PA(2) = Format$(Application.Max(Date, CDate(PA(2))), "yyyy-mm-dd") _
                         Else PA(2) = Format$(Date, "yyyy-mm-dd")
     
        With CreateObject("InternetExplorer.Application")
            .Navigate "http://www.ratp.fr/itineraires/fr/ratp/resultat-detaille/start/" & _
                      Replace(Application.Trim(PA(0)), " ", "+") & "/end/" & _
                      Replace(Application.Trim(PA(1)), " ", "+") & "/is_date_start/1/date/" & _
                      PA(2) & "/time/" & PA(3) & "/route_type/plus_rapide"
     
            While .Busy Or .ReadyState < 4:  DoEvents:  Wend
            TempsRATP = .Document.getElementsByTagName("DL")(0).all(4).innerText
            .Quit
        End With
    End Function

    Piloter Internet Explorer est la méthode la plus lente mais parfois il n'y a pas d'autre possibilité …

    Un peu plus rapide est la fonctionnalité de feuille de calculs Nouvelle requête sur le Web
    aussi programmable en VBA - QueryTable - enfin, quand la page web s'y prête …

    Plus rapide encore est d'utiliser une bibliothèque externe de requêtes
    (WinHttp ou Xml, il y a un tutoriel mais un peu ardu pour un débutant)
    au minimum trois fois plus véloce comparé au pilotage d'Internet Explorer,
    c'est cette méthode employée dans cette nouvelle ébauche de la fonction mais, s'agissant de récupérer uniquement
    une donnée, ne pas s'embêter avec des fonctions web, l'extraire directement du code source de la page (ligne n°34) :

    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
    Sub Demo1()
        MsgBox TempsRATP("15 Av. des Champs-Elysees 75008 Paris", _
                         "69 Boulevard de la Villette 75010 Paris", "25/11/2014", "7:25")
    End Sub
     
    Sub Demo2()
        [C2].Value = TempsRATP([A2].Value, [B2].Value)
    End Sub
     
     
    Function TempsRATP(ParamArray AR())
        Dim PA()
                  If UBound(AR) < 1 Then TempsRATP = "Erreur 1!": Exit Function
        PA = AR:  If UBound(PA) < 3 Then ReDim Preserve PA(3)
               If Not IsDate(PA(3)) Then PA(3) = "8:0"
     
        If IsDate(PA(2)) Then PA(2) = Format$(Application.Max(Date, CDate(PA(2))), "yyyy-mm-dd") _
                         Else PA(2) = Format$(Date, "yyyy-mm-dd")
     
        URL$ = "http://www.ratp.fr/itineraires/fr/ratp/resultat-detaille/start/" & _
               Replace(Application.Trim(PA(0)), " ", "+") & "/end/" & _
               Replace(Application.Trim(PA(1)), " ", "+") & "/is_date_start/1/date/" & _
               PA(2) & "/time/" & PA(3) & "/route_type/plus_rapide"
     
        With CreateObject("Microsoft.XMLHTTP")
            .Open "GET", URL, False
            .setRequestHeader "DNT", "1"
            On Error Resume Next
            .send
            On Error GoTo 0
     
            If .Status = 200 Then
                SP = Split(.responseText, "Le plus rapide&nbsp;: ")
                If UBound(SP) = 1 Then TempsRATP = Val(SP(1)) Else TempsRATP = "Erreur 2!"
                Erase SP
            Else
                TempsRATP = "Erreur " & .Status & " " & .statusText & " !"
            End If
        End With
    End Function
    Je l'ai qualifiée d'ébauche car les fins lecteurs auront remarqué dans la Demo1 la disparition des caractères accentués …
    Contrairement à Internet Explorer dans lequel les caractères accentués passent comme une lettre à la Poste !

    Je m'adresse à Patrick, à Stéphane (l'auteur de l'Excelentissime tutoriel) s'il passe par bonheur ici
    et aux autres chevronnés de l'utilisation d'une bibliothèque de requêtes :
    que ce soit avec la méthode GET ou avec la POST, j'ai essayé divers paramètres via setRequestHeader
    tant au niveau de Accept, accept-charset et particulièrement Content-Type

    Sinon en dehors de supprimer les caractères accentués, je crois bien avoir aperçu une fonction convertissant
    les accents d'une adresse URL (comme l'adresse de la page résultat de la recherche en manuel)
    mais là je ne l'ai pas sous le coude …

    Dernier point : lorqu'il est nécessaire d'enchaîner les requêtes pour intégrer chaque résultat dans une cellule d'une feuille,
    il y a une variante permettant encore de réduire le temps de traitement en suivant alors
    la fameuse chanson de John Lennon, Let It Be ! Voir donc cette contribution

    Lors de ma première mise en place de cette variante, un processus par QueryTable nécessitant presque dix minutes
    (n'en demandait que cinq sur un autre ordinateur dans un autre lieu) est passé sous la barre des trente secondes ‼

    _________________________________________________________________________________________________
    Le savoir est la seule matière qui s'accroit quand on la partage. (Socrate)
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  9. #9
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    Salut

    Pour commencer, merci, comme l'a fait remarquer Marc L, il est plaisant d'avoir un code propre à lire et de plus, je commençais à désespérer de lire une demande qui ne concerne pas les sites boursier!!

    Pour ce qui est de la méthode employée, je pense aussi qu'il y aura des solutions plus robustes et plus performantes mais vu que je suis l'auteur du tuto, je ne vais pas rechigner .
    D'autant que la démarche de compréhension est pour moi parfois plus intéressante que le résultat en lui même, surement un vieux reste d'étudiant moyen ^^, bref.

    Dans le prolongement de ton code voila une solution pour lire tes données:

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    Option Explicit
    Sub PremierIE()
    'Déclaration des variables
    Dim IE As New InternetExplorer
    Dim IEDoc As HTMLDocument
    Dim InputRatpOrigineZoneTexte As HTMLInputElement
    Dim htmlSelectElem As HTMLSelectElement
    Dim InputRatpDestinationZoneTexte As HTMLInputElement
    Dim InputDateDepartZoneTexte As HTMLInputButtonElement
    Dim InputTemps As HTMLGenericElement
    Dim InputRatpBouton As HTMLInputElement
    Dim ElemGen As HTMLGenericElement 'j'utilise ça par rapidité mais libre à toi de déclarer correctement tes variables
    Dim iElement As Integer
     
        'Chargement d'une page web moteur de recherche RATP
        IE.Navigate "http://www.ratp.fr/itineraires/fr/ratp/recherche-avancee"
     
        'Affichage de la fenêtre IE
        IE.Visible = True
     
        'On attend le chargement complet de la page
        WaitIE IE
     
        'On pointe le membre Document
        Set IEDoc = IE.document
     
        'On pointe la première Zone de texte Origine
        Set InputRatpOrigineZoneTexte = IEDoc.all("itineraire[start]")
     
        'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
        'normalement le code est : InputRatpOrigineZoneTexte.Value = ActiveCell(2, 1) mais pour simplifier :
        InputRatpOrigineZoneTexte.Value = "15 Av. des Champs-Élysées 75008 Paris"
     
        'On pointe la seconde Zone de texte Destination
        Set InputRatpDestinationZoneTexte = IEDoc.all("itineraire[end]")
     
        'On définit le texte que l'on souhaite placer à l'intérieur de la zone de départ
        'normalement le code est : InputRatpDestinationZoneTexte.Value = ActiveCell(2, 2) mais pour simplifier :
        InputRatpDestinationZoneTexte.Value = "69 Boulevard de la Villette 75010 Paris"
     
        'On pointe l'heure de départ
        Set htmlSelectElem = IEDoc.all("itineraire[time][hour]")
     
        'On écrit l'heure de départ 7h
        htmlSelectElem.Value = "7"
     
        'On pointe les minutes de départ : 25 par exemple
        Set htmlSelectElem = IEDoc.all("itineraire[time][minute]")
     
        'On écrit les minutes de départ 6h
        htmlSelectElem.Value = "25"
     
        'On pointe la date de départ le 25/11/2014 par exemple
        Set InputDateDepartZoneTexte = IEDoc.all("itineraire[date]")
     
        'On écrit la date de départ
        InputDateDepartZoneTexte.Value = "25/11/2014"
     
        'On pointe notre bouton
        Set InputRatpBouton = IEDoc.all("action_submit")
     
        'On simule un clic
        InputRatpBouton.Click
     
        'On attend la fin de la recherche
        WaitIE IE
     
        'On sélectionne la valeur dans la page web
        'Set ?? pas id, pas de name, balise dl, dt et dd
        'Il n'y a qu'un seul élément ayant pour class box switch-details
        'On va donc le rechercher
        Set ElemGen = IEDoc.getElementsByClassName("box switch-details")(0)
        'Si tu te pose la question, le (0) en bout de ligne veut dire que l'on prend le 1er élément du tableau renvoyé par la fonction GetElementByClassName
        'Ici il n'y a qu'un seul élément sur la page contenant ce classname mais la fonction renvoie quand même une collection d'une ligne, la collection étant en base 0, l'index du 1er élément est 0.
     
        'Ensuite pour la structure en dl dt
        'En regardant le code source on voit deux choses
        '1/
        'On doit aller justq'à l'élément <dl qui contient la liste dl dt (qui se trouve être le 2ème fils de "box switch-details", soit l'élément 1, on est en base 0, donc 1er élément = index 0, 2ème = index 1
        Set ElemGen = ElemGen.Children(1)
     
        '2/
        'Si tu places un espion sur ElemGen et que tu regarde ces enfants (Children)il correspondent aux éléments dt et dd
        'ici seuls les élément dd nous interesse puisque les dt contiennent les titres (Départ, Durée totale, ...)
        'Il suffit donc de faire une boucle qui ne regarde qu'un élément sur 2
        For iElement = 1 To 7 Step 2
            'On va chercher le innerText de chacun des éléments dd, le innertext est le texte qui apparait sur la page web
            Feuil1.Cells(iElement, "A").Value = Trim(ElemGen.Children(iElement).innerText)
            'Trim permet de supprimer les espaces en début et fin de chaine
        Next
     
        'On copie la valeur sélectionnée
     
     
        'On colle la valeur dans la cellule à droite de la dernière cellule sélectionnée
        'ici la valeur recherchée est 31 min
     
     
        'On libère la variable IE
        Set IE = Nothing
        Set IEDoc = Nothing
     
     
    End Sub
    J'ai commenté le code mais si tu veux plus d'informations n'hésite pas.

    Bonne soirée

    ++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  10. #10
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    Salut

    Voila une solution avec une requête serveur

    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
    Sub XMLReq_RATP()
    'Cette sub va interroger le serveur
    'Il faut activer la bibliothèque Microsoft WinHTTP Service et M$ MSXML
    Dim DemandeFichier As MSXML2.XMLHTTP, URl As String
    Dim IEDoc As New HTMLDocument
    Dim FSys As Object, MonFic
    Dim texte As String
    Dim ElemGen As HTMLGenericElement
     
        'On bloque la mise à jour de l'écran
        'Application.ScreenUpdating = False
     
        'On instancie
        Set DemandeFichier = CreateObject("Microsoft.XMLHTTP")
     
        'On définie l'URL
        URl = "http://www.ratp.fr/itineraires/fr/ratp/resultat-detaille/start/15+Av.+des+Champs-%C3%89lys%C3%A9es+75008+Paris/end/69+Boulevard+de+la+Villette+75010+Paris/is_date_start/1/date/2014-11-25/time/07%3A25%3A00/route_type/plus_rapide"
     
        'On génère la requête
        DemandeFichier.Open "POST", URl, False
        DemandeFichier.setRequestHeader "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
        DemandeFichier.setRequestHeader "Accept-Encoding", "gzip , deflate"
        DemandeFichier.setRequestHeader "Content-Type", "text/html; charset=utf-8"
        'DemandeFichier.setRequestHeader "Content-Length", "240"
        DemandeFichier.setRequestHeader "Cache-Control", "    no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
        DemandeFichier.setRequestHeader "Accept-Language", "fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3"
        DemandeFichier.setRequestHeader "Connection", "keep-alive"
        DemandeFichier.setRequestHeader "Host", "www.ratp.fr"
        DemandeFichier.setRequestHeader "Pragma", "no-cache"  'Ajouté
        DemandeFichier.setRequestHeader "Referer", URl
        DemandeFichier.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.0; rv:29.0) Gecko/20100101 Firefox/29.0"
     
        'On envoie la requete
        DemandeFichier.send
     
        'On place la page web reçu en retour dans un document web
        IEDoc.body.innerHTML = DemandeFichier.responseText
     
        'On recherche l'élément contenant la liste DL DT
        Set ElemGen = IEDoc.getElementsByClassName("box switch-details")(0)
     
        'Ensuite tu retrouves le même code pour aller chercher tes éléments dans la page que te retourne le serveur
        'La partie demande est bien plus rapide ainsi.
     
      End Sub
    Bien sur il reste à constituer la ligne de paramètres pour la rendre évolutive, Marc L à déjà bien avancé ce travail il me semble.

    ++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  11. #11
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut
    Bonsoir,

    Qwazerty
    Voulant faire simple, je me suis intéressé à au code du post #9

    Mais la ligne 80 me pose problème puisque le script s'arrête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set ElemGen = ElemGen.Children(1)
    J'ai un message qui me dit que "variable objet ou variable de bloc With non définie"

    Si j'exécute au pas au pas détaillé, ça passe, et j'obtiens enfin les données

    Reste à les organiser de gauche à droite mais je verrais ça après.

    J'ai même limité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For iElement = 1 To 7 Step 2

    Marc-L

    Le code du post #8 est vraiment performant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub Demo1()
        MsgBox TempsRATP("15 Av. des Champs-Élysées 75008 Paris", _
                         "69 Boulevard de la Villette 75010 Paris", "25/11/2014", "7:25")
    End Sub
     
    Sub Demo2()
        [C2].Value = Val(TempsRATP([A2].Value, [B2].Value))
    End Sub
    Il faut tout de même activer quelques bibliothèques

    J'ai voulu remplacer les données inscrites "15 Av. des Champs-Élysées 75008 Paris" et "69 Boulevard de la Villette 75010 Paris" par des variables (données du tableur) mais le code que j'avais employé auparavant ne fonctionne pas.


    Après, je tenais à vous dire à tous que j'apprécie énormément votre aide.

    Qwazerty, tu es très pédagogue puisque tu décris même les "pourquoi (0) et pas (1)..."
    Tous les matins et soir je lis dans le bus "Microsoft Excel 2003 VBA" manuel fait par MS.
    Et quand je vois les parties, je comprends mieux vos propositions même si je suis très loin de pouvoir de pouvoir les écrire comme ça.
    Bref, c'est bien sympa.


    Je lu vos posts où vous parilez des différentes versions de Windows et d'Excel
    Si mon code initial fonctionne chez moi (Vista 32 bits - Office 2010 32 bits) au bureau, ça ne fonctionne pas du tout.... (W7 64 bits Excel 64 bits). Bizarre.

  12. #12
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Merci de ton intervention Stéphane ! J'ai aussi souvent croisé des demandes concernant des sites financiers …

    Dans la ligne n°17 de ton code du post #10, les caractères accentués sont déjà convertis dans l'URL, comme cela aussi je n'ai pas eu de souci.
    Mais dans le cas de l'auteur de cette discussion devant calculer le temps de parcours d'une plage de cellules d'adresses,
    quel serait la méthode pour convertir celles avec des caractères accentués ?

    A part une procédure "maison" avec une table de correspondance, je crois bien avoir vu une fonction mais je ne la retrouve pas, une idée ?


    yuck, mes codes ne nécessitent aucune référence !
    En activer est juste utile durant la phase de développement pour accéder à la racine du document par exemple …

    J'ai édité la procédure Demo2 du dernier code du post #8 car la requête de renvoyant qu'une valeur numérique, la fonction Val est inutile
    et comme cela les messages éventuels d'erreurs sont conservés (sinon Val les convertit en zéro) …

    Les soucis notamment avec getElementsByClassName sont focalisés sous Seven (sauf pour IE9) et c'est indépendant de la version d'Excel.
    Un code pilotant IE 10 peut être problématique sous Seven, ce même code fonctionnant bien sous Windows 8 !
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  13. #13
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Dans mon cas, pas besoin de supprimer les accents car je passe toutes mes adresses en majuscules....
    Les moteurs de recherche d'itinéraires préfèrent tjs les adresses en majuscules....

    Et effectivement, je suis sous seven/IE10 au boulot et vista/IE 10 @home

  14. #14
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Ok pour les majuscules mais comme dans l'exemple initial les adresses ont des caractères accentués …
    La solution est donc déjà présente dans les précédents codes.

    Mais je suis toujours preneur si quelqu'un trouve la fonction de conversion en adresse URL avec accents convertis !

    yuck, si les adresses sont en un seul bloc (sans colonne ni ligne vide), voir les propriétés CurrentRegion, Rows, Columns, Count
    et Cells pour les parcourir, le tout englobé dans une boucle …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  15. #15
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    Salut

    Voila une solution pour éviter ce bug
    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
        WaitIE IE
     
        'On sélectionne la valeur dans la page web
        'Set ?? pas id, pas de name, balise dl, dt et dd
        'Il n'y a qu'un seul élément ayant pour class box switch-details
        'On va donc le rechercher
     
        'Visiblement le waitIE ne suffit pas, l'élément "box switch-details" n'est pas chargé à la fin de waitIE...
        'Une solution est de boucler pour attendre mais attention aux boucles infinies...
        'Pour mieux controler le temps d'attente, tu peux ajouter un sleep dans la boucle (je te laisse chercher la déclaration de l'API windows Sleep
        'Car en fonction de la puissance de ton PC il va effectuer les boucle plus ou moins rapidement.
        Do Until Not ElemGen Is Nothing
            Set ElemGen = IEDoc.getElementsByClassName("box switch-details")(0)
            DoEvents
            'Sleep(20) 'attend 20ms
            iFois = iFois + 1
            If iFois = 2000 Then 'attention à diminuer ifois si sleep est utilisé sinon 2000 x 20ms = presque 7min
                MsgBox "Attendre le chargement complet et cliquez sur OK", , ":/ Attente"
                iFois = 0
            End If
        Loop
    Par contre je ne comprends pas ta modification de la boucle for, si tu veux uniquement l'élément 3, supprime carrément la boucle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil1.Range("A1").Value = Trim(ElemGen.Children(3).innerText)

    @Marc L. : En effet ce problème me semblait accessoire , voila le code qui y est proposé (non testé)

    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
    Public Function URLEncode( _
       StringVal As String, _
       Optional SpaceAsPlus As Boolean = False _
    ) As String
     
      Dim StringLen As Long: StringLen = Len(StringVal)
     
      If StringLen > 0 Then
        ReDim result(StringLen) As String
        Dim i As Long, CharCode As Integer
        Dim Char As String, Space As String
     
        If SpaceAsPlus Then Space = "+" Else Space = "%20"
     
        For i = 1 To StringLen
          Char = Mid$(StringVal, i, 1)
          CharCode = Asc(Char)
          Select Case CharCode
            Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
              result(i) = Char
            Case 32
              result(i) = Space
            Case 0 To 15
              result(i) = "%0" & Hex(CharCode)
            Case Else
              result(i) = "%" & Hex(CharCode)
          End Select
        Next i
        URLEncode = Join(result, "")
      End If
    End Function
    ++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  16. #16
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Merci Stéphane ‼

    J'ai revisité la fonction du lien via la bibliothèque Script Control à ma sauce sans la référencer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Function Convert2URL$(TXT$)
        With CreateObject("MSScriptControl.ScriptControl")
            .Language = "JScript"
            .AddCode "function encode(txt) {return encodeURIComponent(txt);}"
             Convert2URL = .Run("encode", TXT)
        End With
    End Function
     
     
    Sub TestURLratp()
        MsgBox Replace(Convert2URL("15 Av. des Champs-Élysées 75008 Paris"), "%20", "+")
    End Sub
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  17. #17
    Membre à l'essai
    Homme Profil pro
    Urbaniste
    Inscrit en
    Octobre 2014
    Messages
    40
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Transports

    Informations forums :
    Inscription : Octobre 2014
    Messages : 40
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par Qwazerty Voir le message
    Salut

    Voila une solution pour éviter ce bug
    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
        WaitIE IE
     
        'On sélectionne la valeur dans la page web
        'Set ?? pas id, pas de name, balise dl, dt et dd
        'Il n'y a qu'un seul élément ayant pour class box switch-details
        'On va donc le rechercher
     
        'Visiblement le waitIE ne suffit pas, l'élément "box switch-details" n'est pas chargé à la fin de waitIE...
        'Une solution est de boucler pour attendre mais attention aux boucles infinies...
        'Pour mieux controler le temps d'attente, tu peux ajouter un sleep dans la boucle (je te laisse chercher la déclaration de l'API windows Sleep
        'Car en fonction de la puissance de ton PC il va effectuer les boucle plus ou moins rapidement.
        Do Until Not ElemGen Is Nothing
            Set ElemGen = IEDoc.getElementsByClassName("box switch-details")(0)
            DoEvents
            'Sleep(20) 'attend 20ms
            iFois = iFois + 1
            If iFois = 2000 Then 'attention à diminuer ifois si sleep est utilisé sinon 2000 x 20ms = presque 7min
                MsgBox "Attendre le chargement complet et cliquez sur OK", , ":/ Attente"
                iFois = 0
            End If
        Loop
    Vu que je n'y arrivais pas car il me demandait de déclarer mes variables, j'ai trouvé une autre solution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Function WaitIE(oIE As InternetExplorer, Optional pTimeOut As Long = 0) As Boolean
    Dim lTimer As Double
    lTimer = Timer
    Do
        DoEvents
       If oIE.readyState = READYSTATE_COMPLETE And Not oIE.Busy Then Exit Do
       If pTimeOut > 0 And Timer - lTimer > pTimeOut Then
           WaitIE = True
           Exit Do
       End If
    Loop
    comme ça même pas besoin de trouver le "bon" temps d'attente

    Bon, ça fonctionne reste à mettre le résultat en face de la bonne ligne et de faire une boucle

    Merci Qwazerty pour avoir compris le problème. Je pense qu'il suffisait de marquer "= READYSTATE_COMPLETE" pour que ça fonctionne ; apparemment non...

  18. #18
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut


    yuck,

    ne pas confondre attendre la fin du chargement de la page initiale avec attendre la mise à jour de la page !

    La solution est pourtant déjà présente dans le premier code du post #3, comparer les lignes n°13 (IE) & 25 (IEDoc) …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  19. #19
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut




    Suite des posts #15 & 16 : la conversion d'une chaîne en URL est intégrée depuis la version 2013

    dans une fonction de feuille de calculs : WorksheetFunction.EncodeUrl

    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  20. #20
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    Salut

    Cool pour la fonction encodeURL.

    Pour ta version de WaitIE, l'utilisation de Timer (que je n'avais de mémoire jamais utilisé) est intéressante mais j'avoue ne jamais faire cela, attendre x seconde avant de considérer que la page est entièrement chargée, je préfère trouver une indication dans la page qui m'indique que celle-ci a belle et bien terminée sont chargement (cf mon code ou je contrôle la présence d'un élément particulier).

    Pour ce qui est de WaitIE, c'est une boucle d'attente basique qui va fonctionner dans 90% des cas. Pour les 10% qui restent il faut trouver une façon plus adaptée de rechercher de détecter la fin du chargement.

    ++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 5 12345 DernièreDernière

Discussions similaires

  1. Réponses: 11
    Dernier message: 06/02/2013, 15h25
  2. Afficher le résultat d'une requête MySQL comme dans phpMyAdmin
    Par mathieu dans le forum Contribuez / Téléchargez Sources et Outils
    Réponses: 0
    Dernier message: 14/02/2011, 18h48
  3. [AC-2003] Tester si une cellule est vide dans un classeur excel et faire une boucle
    Par moilou2 dans le forum VBA Access
    Réponses: 11
    Dernier message: 19/08/2009, 09h34
  4. afficher résultat d'une requête dans page web(ici jsp)
    Par troussepoil dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 14/06/2009, 12h18

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