Link to home
Start Free TrialLog in
Avatar of stefanpantu
stefanpantu

asked on

Finding out if instance of IE is busy/ready with InternetExplorer Automation

Using VBA, trying to find out if IE has stopped downloading a web page with two frames.

This question is very similar to the question/answer at

https://www.experts-exchange.com/questions/20529021/Internet-Explorer-ActiveX-Control-busy-property-doesn't-work-in-do-loop.html?query=.busy&topics=93

in which the .busy and .ReadyState attributes of the WebBrowser control do not work and therefore the busy/readystate status of IE must be monitored with the IE_DownloadComplete event.  I am experiencing the EXACT problem described in Q_20529021.

I have two questions regarding this issue :

1.  On a page with frames, could it be possible that each frame has a .busy or .readystate attribute, something like

 IE.Document.frames(1).Document.forms(0).busy

and therefore you would have to check the .busy/.readystate attribute of each frame instead of the usual IE.busy ?

2.  If frames do not have their own .busy/.readystate  attributes then the IE_DownloadComplete event must be used to check the status of the IE instance.  

For compatibility reasons I can not use the WebBrowser control.  I can check the status of the IE instance using the IE_DownloadComplete event.  The code for the event is:

  Private Sub IE_DownloadComplete(ByVal pDisp As Object, URL As Variant)
   Debug.Print "Download Is Complete"
  End Sub

but the event is not linked to an object.  How can I link this event to the IE instance given that I am not using a WebBrowserControl?  Are there any other ways to check if the IE instance has stopped processing a web page?

Avatar of thunder_moose
thunder_moose

Hi there,

I don't think each frame has it's own readystate. I think the entire webpage is treated as one entity. I had the same problem as you, but changed my code to the following, it works fine for me:

Set oIE = New InternetExplorer
oIE.navigate ("http://www.website.com")
Do Until oIE.readyState = READYSTATE_COMPLETE
   DoEvents
Loop

Ofcourse if you want to physically see the browser work, you'll have to add oIE.visible = true.

I hope this helps,
tm
Perhaps you could also tell us what you want to do with the IE control... I use it in an application to extract some elements of the HTML for example.

tm
Avatar of stefanpantu

ASKER

If anyone knows how to use the  IE_DownloadComplete outside of the WebBrowser control, I'm sure this is the correct way to solve this problem.  I can't use WebBrowser for compatibility reasons (my app needs to check for the presence of IE 6)

My code and Debug output is below.  In all my experience with  READYSTATE_COMPLETE, it is only different from 4 when a new instance of a browser is first opened.  After a browser is opened READYSTATE_COMPLETE is always 4 (see debug output below).

I was only able to check for specific HTML text after loading this page to make sure a page had completely loaded.  That's clumsy, but not as clumsy as adding a statement like

 Application.Wait (Now + TimeValue("0:00:01"))

It's the only way I was able to get a button click to work to open the final page.  And if the server is slow, then I'm sure this code will break.

Function TestLogonIE() As Boolean
'test to autologon into quote website
 
 Dim IE As Object
 Dim form0 As Object
 Dim document1 As Object
 
 Dim hwnd As Long
 Dim oForm As Object
 Dim ieClipboard As Object
 Dim clipboardContents As String
 Static errorStartTime As Date
 
 On Error GoTo ErrorHandler
 
 Set IE = New InternetExplorer
 With IE
  .Navigate "http://www.alaron.ranweb.com/login/alr.asp"
  .Visible = False 'show/hide browser
  .Silent = True 'suppress dialog boxes
 End With
 Call WaitIE(IE) 'wait to load link, ReadyState seems to be set
                 'to a value other than 4 only when browser is opened
 
 Set form0 = IE.document.frames(1).document.forms(0)
 Set document1 = IE.document.frames(1).document

 form0.elements("Username").Value = Username
 form0.elements("Password").Value = Password
 document1.images("ImageLogOn").Click
 Call WaitIEHTML(IE, "Quote")
 Debug.Print "Quote Request Page Loaded, " & "ReadyState: " & CStr(IE.ReadyState)
 
 Set form0 = IE.document.frames(1).document.forms(0) 'repoint to new webpage
 
 form0.elements("O_QC").Value = "spx4 c1190" 'goto error 91 if page not loaded
 Application.Wait (Now + TimeValue("0:00:01")) 'don't like Waiting a second here,
                                               'but it's the only way to get the next .Click to work
 Debug.Print "Quote Set, " & "ReadyState: " & CStr(IE.ReadyState)
 
 document1.images("QC_G").Click 'Click Go button to display quote page
 Call WaitIEHTML(IE, "Key:Real-time QuoteDelayed QuoteInvalid Contract") 'wait for this text
 Debug.Print "Quote Go Button Clicked, " & "ReadyState: " & CStr(IE.ReadyState)
 
 form0.elements("O_QC").Click 'select the right frame
 Debug.Print "Select the right frame button click, " & "ReadyState: " & CStr(IE.ReadyState)
 
 IE.ExecWB OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT
 IE.ExecWB OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT
 Debug.Print "Quote Page Copied To Clipboard," & "ReadyState: " & CStr(IE.ReadyState)
 
 Set ieClipboard = New DataObject
 ieClipboard.GetFromClipboard
 clipboardContents = ieClipboard.GetText(1)
 'clipboardContents = document1.Selection.createRange.Text 'this works if text is selected, but no delimitors
 'clipboardContents = document1.body.innertext ' this also works, but again no delimitors!
 
 Set ieClipboard = Nothing
 Set form0 = Nothing
 Set document1 = Nothing
 Set IE = Nothing
 
 errorStartTime = #12:00:00 AM#
 Exit Function
 
ErrorHandler:

 Select Case Err.Number
   
   Case 91 'Object Variable or With Block Not Set (IE DOM error)
   
    If errorStartTime = #12:00:00 AM# Then
     errorStartTime = Time
    End If
    If errorStartTime <> #12:00:00 AM# Then
     If Time > TimeSerial(Hour(errorStartTime), Minute(errorStartTime) + 1, Second(errorStartTime)) Then Exit Function
    End If
    Debug.Print "Ran Error Handler"
    DoEvents
    Resume
   
   Case Else
    Debug.Print CStr(Err.Number) & ": " & Err.Description
   
 End Select

End Function

Private Sub WaitIE(IE As Object)

 Do
  DoEvents 'wait until IE is done loading page.
  Debug.Print "Waiting..."
 Loop Until IE.ReadyState = READYSTATE_COMPLETE

End Sub

Private Sub WaitIEHTML(IE As Object, HTMLSearchText As String)
'wait for some specific HTML text to be displayed on the page

 Do
  DoEvents 'wait until IE is done loading page.
  Debug.Print "Waiting IEHTML..."
 Loop Until CBool(InStr(1, IE.document.frames(1).document.body.innertext, HTMLSearchText))

End Sub

------------------------------------------

Output:

   .
   .
   .
Waiting...
Waiting...
   .
   .
   .
Waiting IEHTML...
Quote Request Page Loaded, ReadyState: 4
Quote Set, ReadyState: 4
  .
   .
   .
Waiting IEHTML...
Waiting IEHTML...
Waiting IEHTML...
Quote Go Button Clicked, ReadyState: 4
Select the right frame button click, ReadyState: 4
Quote Page Copied To Clipboard,ReadyState: 4



ASKER CERTIFIED SOLUTION
Avatar of thunder_moose
thunder_moose

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I don't quit understand your question. Why you cannot tie up to the event


just declare on the top of your form as


dim WithEvents IE as New InternetExplorer


check with this

http://www.angelfire.com/realm/vb-shared/IEDOM_Tip01.htm