Solved

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

Posted on 2004-09-22
8
668 Views
Last Modified: 2013-11-25
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

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_20529021.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?

0
Comment
Question by:stefanpantu
  • 3
8 Comments
 
LVL 3

Expert Comment

by:thunder_moose
ID: 12130779
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
0
 
LVL 3

Expert Comment

by:thunder_moose
ID: 12130829
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
0
 

Author Comment

by:stefanpantu
ID: 12140106
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



0
 
LVL 3

Accepted Solution

by:
thunder_moose earned 500 total points
ID: 12140848
Hey there,

Again, I used to have the same problems, but my program is used by a lot of people in the company on a regular basis and it's working flawlessly using READYSTATE_COMPLETE.

Firstly, one thing that I notice in your code, is the IE.Visible = False thing. I used to have that in and it caused a lot of problems. The browser starts up invisible anyway, so you don't need that statement. If you put it in the browser seems to briefly flash in the taskbar.

Secondly: your declarations are a bit vague. It won't make a difference in the code working, but make it a bit easier to see which properties and so on are available to you.

Dim IE As New InternetExplorer
Dim document1 As HTMLDocument

You say that each time you call IE and it finished exploring to a page it remains in the READYSTATE_COMPLETE Readystate? Why not just quit it after each call? IE.Quit?

In my code I have it like this:

Sub NavigateToSite(strWebsite As String)
   'Navigate to default.aspx, wait until page is fully loaded
   Set oIE = New InternetExplorer
   oIE.navigate (strWebsite)
   Do Until oIE.readyState = READYSTATE_COMPLETE
       DoEvents
   Loop
   Set oIEDoc = oIE.Document

   'Check to see if document could be loaded, if not quit program
   If oIEDoc.Title = "Cannot find server" Then
      MsgBox "The Sever is Unreachable"  
      End
   End If
...
...Code to go through HTML content of file and do what I need
...
   'Quit IE, release variables
   oIE.Quit
   Set oIE = Nothing
   Set oIEDoc = Nothing
End Sub

I also had the page not loading entirely, also checked for tags in HTML to see if it's done. It used to work 2 out of 3 times and sometimes crash, but like it is now, it works perfectly. I honestly just think that you have something in the wrong place.

Regards,
TM
0
 
LVL 26

Expert Comment

by:EDDYKT
ID: 12141797
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
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now