VBA Access Webbrowsers... SUPER DEFI!!!

Hello à tous,
j'ai un super défit pour tous les amateurs de programmation.
J'ai dans une base de données Access deux WebBrowser. En gros ce sont des controles ActivX qui permettent d'intégrer des browsers web basés sur IE sur un formulaire access. Rien de chinois jusque là.
Après bien des manips, j'ai réussis à en faire plus ou moins ce que je voulais.
Le seul problème, c'est que l'intérêt majeur de ce programme vient de son "refresh automatique".
Toutes les x minutes (peu importe x), les pages des webbrowsers sont rafrachies automatiquement, évitant à ses utilisateurs d'être éjectés comme des malpropres par un timeout dû à leur inactivité.
A ce point, je précise que ce programme est uniquement dans un but professionel pour mon boulot. Il n'est pas question ici de tricher sur certains sites pour faire croire qu'on y est resté des heures de façons à avoir des points ou Dieu sait quoi...
Bref! Mon problème c'est qu'une fois le "logon" sur le site effectué, un message apparait à chaque refresh : "The page cannot be refreshed without resending the information. Click Retry to send the information again, or click Cancel to return to the page that you were trying to view."
Donc si je comprend bien, étant donné que l'utilisateur est loggé, chaque click renvoie des informations pour permettre au serveur de savoir qui il est. Mais dans le cadre de ce programme, c'est fort embêtant...
Serait-il possible de se débarasser de ce message en l'interceptant dans mon code (par exemple) ?
Je pense qu'une option d'IE permet de se débarrasser de ce genre de messages (ce qui pourrait marcher vu que les webbrowsers sont basés sur IE), mais ici au travail on ne peut pas paramétrer IE...

Merci à tous les génies qui trouveraient une solution à ce problème...

--

Aides-toi et le ciel t'aidera...
Configuration: Windows XP
Internet Explorer 6.0

8 réponses

  1. Ton problème est simple. Quand on se logge sur un site, la connexion reste allumée (keep alive). Sur le web, il y a 4 façons de faire se conserver les données d'une page à l'autre:

    Par cookie (j'imagine tu sais c'est quoi)
    Par variable de session (c'est du côté serveur)
    Par variables en GET (regarde l'url... le ?id=44242&action=supprimer ....)
    Par variable POST (invisible, c'est dans le browser)

    Quand tu fait ton refresh, si la page fonctionne avec un POST, il faut réenvoyer les variables... c'est obligatoire!! Et si on les réenvoies, c'est dangereux car si ce sont des données sensibles, ou qu'il y a un risque de double-post ou de doublon, l'utilisateur DOIT confirmer, ce qui dans ton cas ne se fait pas.

    Il y a une solution. Avec le contrôle, la méthode

    object.Navigate2( _
    URL As Variant, _
    [Flags As Variant,] _
    [TargetFrameName As Variant,] _
    [PostData As Variant,] _
    [Headers As Variant])

    Permet de spécifier PostData, qui contient les données POST. Donc il ne les demanderas pas.

    Pour obtenir ses données, si tu intercepte l'évènement:
    BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)

    tu pourras obtenir ce "PostData" et l'envoyer plus tard en faisant ton navigate2

    Sinon, il y a refresh2, qui pourrait peut-être marché, car tu peux lui spécifier les options:
    REFRESH_NORMAL = 0,
    REFRESH_IFEXPIRED = 1,
    REFRESH_COMPLETELY = 3
    comme paramètre de level

    Sur ce, essaye, je suis currieux. Moi chez moi je n'ai pas réussi à reproduire ton truc.

    Gloire à Windows!
    -Deadly Predator
    1. Contributeur
      J'y aurais jamais pensé!
      Je vais essayer ça de suite et je te tiens au courant.
      Dans tous les cas, que ça marche ou pas t'es un chef, rien que pour y avoir pensé ^^
      1. Contributeur
        Hum.......
        En fait j'ai un problème.
        Je veux récupérer l'URL de la page actuelle pour la renvoyer mais Access ne reconnait pas la propriété "url"... "Object doesn't support this property or methode".
        Par ailleurs je ne sais pas trop comment construire ma méthode Navigate2...
        J'ai essayé Refresh2 avec 3 comme paramètre mais j'ai exactement le même message qu'avant... :-/
        1. ce n'est pas URL la propriété qu'il te faut, mais bien LocationURL
          exemple:
          controleWeb.LocationURL

          ta méthode navigate2 n'est pas si complexe:

          controleWeb.navigate2 url, 0, "_self", postData

          où URL est l'URL de la page, et postData les données de post que tu as pu obtenir en interceptant BeforeNavigate2. Cependant, avec BeforeNavigate2, assure toi que le Url de l'évèmement soit bel et bien celui de la page que tu spécifie dans le URL du navigate 2.

          exemple, pseudo vb code
          dim postDataPage
          dim urlPage
          
          sub initialization()
          url = "https://www.lesite.com/"
          demarrerBoucle...
          end sub
          
          sub aChaqueXMin()
          controleWeb.navigate2 url, 0, "_self", postData
          end sub
          
          Private Sub object_BeforeNavigate2( ByVal pDisp As Object, ByRef Url As Variant, ByRef Flags As Variant, ByRef TargetFrameName As Variant, ByRef PostData As Variant, ByRef Headers As Variant, ByRef Cancel As Boolean)
          if(urlPage = Url and PostData <> Nothing) then
          postDataPage= postData
          end if 
          end sub
          

          donne moi en des nouvelles
          1. Contributeur
            Ouééééééééééééé.
            J'viens de me faire avoir...
            En fait j'ai fais +/- ce que tu m'as dis... J'ai intercepté les navigates2 avec le "before".
            Grâce à ça j'ai récupérer les paramètres dont le Post. Et de là j'ai relancé une procédure qui lance le navigate2 avec les paramètres obtenus.
            La conneries, c'est que le navigate2 lancé se fait lui même attrapé par le BeforeNavigate qui en relance un autre qui se fait aussi avoir et ainsi de suite... boucle infinie.
            J'ai horreur de ça...
            J'vais appeler le service informatique pour qu'ils me kill ma session vu que je suis au taf et je retest plus intelligemment...
            je te tiens au courant ;o)
            1. Contributeur
              Bon je te montre ce que j'ai fais jusque maintenant...
              La fonction BeforeNavigate2 copie les paramètres dans des variables globales.
              Si la fonction BeforeNavigate2 a été appelée par la fonction SendN1, alors elle ne la relance pas, sinon elle la lance.
              La fonction SendN1 effectue le navigate2 avec les nouveaux params.
              J'ai testé tel quel et je me suis fais éjecté (j'ai prévu une boucle dans BeforeNavigate2 pour m'éjecter du formulaire en cas de boucle infinie).

              Private Sub WebB1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
              u1 = URL
              p1 = PostData
              f1 = Flags
              t1 = TargetFrameName h1 = Headers
              Cancel = True

              If indnav = True Then
              Call SendN1
              End If

              i = i + 1
              If i >= 20 Then
              DoCmd.Close acForm, Me.Name
              End If

              End Sub

              Sub SendN1()

              Dim i As Variant

              indnav = False
              i = WebB1.Navigate2(u1, 0, "_self", p1, h1)

              indnav = True

              End Sub


              Tiens sinon comment est-ce que tu fais pour formatter ton code dans tes messages sur CCM ?
              1. J'ai de quoi de fonctionnel!! Voici le code

                Option Compare Database
                
                
                Const tempsSeconde = 10
                
                Dim postDataPage
                Dim urlPage
                Dim bStopBoucle
                
                Private Sub btnAccueil_Click()
                webBrowser.GoHome
                End Sub
                
                Private Sub btnGo_Click()
                goBrowser txtURL.Value
                End Sub
                
                Public Sub goBrowser(url As String)
                On Error Resume Next
                bStopBoucle = False
                urlPage = url
                webBrowser.Navigate2 urlPage, 0, "_self"
                Do Until bStopBoucle
                    Dim dateDebut
                    dateDebut = Now
                    Do Until ((Abs(DateDiff("s", Now, dateDebut)) > tempsSeconde And webBrowser.ReadyState >= 2) Or bStopBoucle)
                    DoEvents
                    Loop
                    txtPOST.Value = postDataPage
                    webBrowser.Navigate2 urlPage, &H4 Or &H8, "_self", postDataPage
                Loop
                End Sub
                
                Private Sub btnNext_Click()
                On Error Resume Next
                webBrowser.GoForward
                End Sub
                
                Private Sub btnRefresh_Click()
                On Error Resume Next
                webBrowser.Refresh2 3
                End Sub
                
                Private Sub btnPrecedent_Click()
                On Error Resume Next
                webBrowser.GoBack
                End Sub
                
                Private Sub btnStop_Click()
                webBrowser.Stop
                End Sub
                
                Private Sub btnStopBoucle_Click()
                bStopBoucle = True
                End Sub
                
                Private Sub webBrowser_DocumentComplete(ByVal pDisp As Object, url As Variant)
                txtURL.Value = url
                urlPage = url
                'If (URL = urlPage) Then
                'Dim dateDebut
                'dateDebut = Now
                'Do Until (DateDiff("s", Now, dateDebut) > tempsSeconde)
                'DoEvents
                'Loop
                'webBrowser.Navigate2 urlPage, 0, "_self", postDataPage
                'End If
                End Sub
                
                Private Sub webBrowser_BeforeNavigate2(ByVal pDisp As Object, url As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
                On Error Resume Next
                Dim strResult
                strResult = ""
                Dim bytes As Variant
                bytes = CVar(PostData)
                For I = 0 To UBound(bytes)
                strResult = strResult & Chr(bytes(I))
                Next
                'If (url = urlPage) Then
                If (txtPOST.Value = Null) Then
                txtPOST.Value = vbNullString
                End If
                If (strResult <> vbNullString) Then
                txtPOST.Value = Now & ": " & vbCrLf & strResult & vbCrLf & "-----------------" & txtPOST.Value
                End If
                postDataPage = PostData
                'End If
                End Sub
                
                


                C'est vraiment tout croche mais ça marche. Ce code est à mettre dans ton form

                ce qui commence par btn est un bouton de commande, donc place
                btnAccueil, btnGo, btnRefresh, ...
                et les txt c'est des boites de texte.
                Il te faut txtURL, qui va contenir l'URL
                et txtPOST, qui va afficher les variables POST en cours.

                Au pire je t'envoie le mdb par courriel...
                1. Contributeur
                  Bon j'ai trouvé une solution qui marche \o/
                  En grande partie grâce à ton aide:)
                  Je t'envoie le code que j'ai finalement obtenu avec les commentaires.

                  Option Compare Database

                  ''''''''''''''''''''''
                  ' VARIABLES GLOBALES '
                  ''''''''''''''''''''''

                  Dim indr As Boolean ' Indice de rafraichissement automatique
                  Dim indw1 As Boolean ' Indice qui indique si WebB1 est déjà passé dans Before_Navigate2 (paramètres initialisés)
                  Dim indw2 As Boolean ' Indice qui indique si WebB2 est déjà passé dans Before_Navigate2 (paramètres initialisés)
                  Dim u1 As Variant ' Paramètres pour le chargement des pages
                  Dim u2 As Variant '
                  Dim p1 As Variant '
                  Dim p2 As Variant '
                  Dim f1 As Variant '
                  Dim f2 As Variant '
                  Dim t1 As Variant '
                  Dim t2 As Variant '
                  Dim h1 As Variant '
                  Dim h2 As Variant '

                  ''''''''''''''''''''''''''''''''''''''''''''''''''
                  ' CLICK SUR LE BOUTON DE RAFRAICHISSEMENT ON/OFF '
                  ''''''''''''''''''''''''''''''''''''''''''''''''''

                  Private Sub ButR_Click()

                  If indr = True Then ' Si le rafrachissement automatique est activé, le désactiver
                  ButR.Caption = "Start automatic refresh"
                  ButR.ControlTipText = "The automatic refresh is deactivated"
                  indr = False
                  Else ' Sinon, l'activer
                  ButR.Caption = "Stop automatic refresh"
                  ButR.ControlTipText = "The automatic refresh is activated"
                  indr = True
                  End If

                  End Sub

                  Private Sub Form_Load()

                  ' Si les WebBrowsers son visibles, le redimensionnement ne marche pas
                  WebB1.Visible = False
                  WebB2.Visible = False

                  ' Redimensionnement du WebBrowser de gauche
                  With WebB1
                  .Height = CInt(Form.WindowHeight) - 3000
                  .Width = CInt(Form.WindowWidth / 2)
                  .Top = 0
                  .Left = 0
                  End With

                  ' Redimensionnement du WebBrowser de droite
                  With WebB2
                  .Height = CInt(Form.WindowHeight) - 3000
                  .Width = CInt(Form.WindowWidth / 2)
                  .Top = 0
                  .Left = CInt(Form.WindowWidth / 2)
                  End With

                  ' Affichage des WebBrowsers
                  WebB1.Visible = True
                  WebB2.Visible = True

                  End Sub

                  '''''''''''''''''''''''''''
                  ' OUVERTURE DU FORMULAIRE '
                  '''''''''''''''''''''''''''
                  Private Sub Form_Open(Cancel As Integer)

                  ' Redimensionnement et position du bouton de rafraichissement
                  ButR.Height = 1000
                  ButR.Width = 2000
                  ButR.Left = 0
                  ButR.Top = CInt(Form.WindowHeight) - 3000

                  indnav = True
                  indw1 = False
                  indw2 = False

                  ' WebBrowsers à la page de l'intranet
                  WebB1.Navigate2 "xxx"
                  WebB2.Navigate2 "xxx"

                  ' Initialisation du bouton de rafrachissement
                  indr = True
                  ButR.ControlTipText = "The automatic refresh is activated"
                  ' Si les WebBrowsers son visibles, le redimensionnement ne marche pas
                  'WebB1.Visible = False
                  'WebB2.Visible = False

                  ' Redimensionnement du WebBrowser de gauche
                  'With WebB1
                  '.Height = CInt(Form.WindowHeight) - 3000
                  '.Width = CInt(Form.WindowWidth / 2)
                  '.Top = 0
                  '.Left = 0
                  'End With

                  ' Redimensionnement du WebBrowser de droite
                  'With WebB2
                  '.Height = CInt(Form.WindowHeight) - 3000
                  '.Width = CInt(Form.WindowWidth / 2)
                  '.Top = 0
                  '.Left = CInt(Form.WindowWidth / 2)
                  'End With

                  ' Affichage des WebBrowsers
                  'WebB1.Visible = True
                  'WebB2.Visible = True
                  ' Focus sur le WebBrowser de gauche
                  WebB1.SetFocus

                  Form.Repaint
                  Form.Refresh
                  Form.Repaint

                  End Sub

                  '''''''''''''''''''''''''''''''
                  ' RAFRACHISSEMENT AUTOMATIQUE '
                  '''''''''''''''''''''''''''''''
                  Private Sub Form_Timer()

                  If indr = True Then
                  If indw1 = True Then
                  WebB1.Navigate2 u1, f1, t1, p1, h1
                  Else
                  WebB1.Navigate2 "xxx"
                  End If
                  If indw2 = True Then
                  WebB2.Navigate2 u2, f2, t2, p2, h2
                  Else
                  WebB2.Navigate2 "xxx"
                  End If
                  End If

                  End Sub

                  Private Sub WebB1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
                  u1 = URL
                  p1 = PostData
                  f1 = Flags
                  t1 = TargetFrameName h1 = Headers

                  indw1 = True

                  End Sub

                  Private Sub WebB2_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
                  u2 = URL
                  p2 = PostData
                  f2 = Flags
                  t2 = TargetFrameName h2 = Headers

                  indw2 = True

                  End Sub

                  Où xxx est l'adresse de la page initiale.
                  Seul bémol à l'affichage. Je ne sais pas pourquoi mais les webbrowsers ne se redimensionnent pas.
                  En fait, si je lance une première fois, ils ne sont pas redimensionnés. Mais si je mets le form en details puis que je le lance, là ils s'affichent comme il faut.
                  Très bizarre...
                  Le code en commentaire dans la sub Form_Load était utilisé comme test. Mais même en mettant ce code (activé) dans le Form_Load ça ne change rien...
                  J'ai bien l'impression que j'en ai pas fini avec ce fichu formulaire :-/

                  Merci énormément pour ton aide en tout cas. J'y serais pas arrivé sinon ^^