Internet Explorer automation in Word XP

J

Jonathan Sachs

I have a VBA application which loads and reads Web pages through
Internet Explorer. I last used it a couple of months ago with Word
2000 under Windows 2000, and it worked correctly. I am now running on
a Windows XP machine with Word XP, and it doesn't work.

I load Internet Explorer in a class module and use the
DocumentComplete event to make the application wait while a page is
being loaded. Here are the relevant parts of the code:

Private Const pageLoadTimeout As Single = 30 ' 30 second
timeout to load page.
Public WithEvents explorerObject As InternetExplorer
Private explorerWait As Boolean

' The DocumentComplete event routine.
Private Sub explorerObject_DocumentComplete(ByVal pDisp As Object, url
As Variant)
On Error Resume Next
If pDisp Is Nothing Then Exit Sub
If pDisp.Document Is Nothing Then Exit Sub
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Exit Sub
End If
On Error GoTo 0
explorerWait = False
End Sub

' Called after a page is loaded to wait until load is complete.
Private Function waitForDocumentComplete() As Boolean
Dim before As Single, after As Single
before = Timer
Do While explorerWait
after = Timer
If after < before Then before = before - 24 * 60 * 60 ' 'round
Midnight
If after - before > pageLoadTimeout Then
MsgBox "Browser timed out loading page " +
explorerObject.Document.url, vbOKOnly
waitForDocumentComplete = False
Exit Function
End If
DoEvents

If Me.explorerObject.Document.body.all.length > 0 Then
explorerWait = False
Loop
waitForDocumentComplete = True
End Function

' One of several functions that load a page, presented here as an
' example of how waitForDocumentComplete is used.
Public Function htmlGetBody(url As String) As HTMLBody
' Read the specified URL with the specified browser. Return the
' body.

explorerWait = True
explorerObject.navigate url

If waitForDocumentComplete Then
Set htmlGetBody = Me.explorerObject.Document.body
Else
Call cleanup
End
End If
End Function


I haven't figured out exactly what is going wrong, and I think the
problem is manifesting itself in several ways. One is that a reference
to the expression "Me.explorerObject.Document" generates an Automation
Error when a page is not yet loaded. Setting "On Error Resume Next"
doesn't prevent this, and I haven't found any way of detecting the
condition in code. Another manifestation is that the code sometimes
finds that Me.explorerObject.Document.body.all.length has a value
greater than 0 before loading is complete, and if the program
proceeds, any reference to a tag in the body will return Nothing.

I need to know what changes Microsoft made to this interface, and how
to accommodate them!

My mail address is jsachs177 at earthlink dot net.
 
J

Jonathan Sachs

This is getting weirder.

Returning to the problem after some sleep, I instrumented the
"waitForDocumentComplete" routine and the "DocumentComplete" event
routine to display a trace of the execution path. Then I loaded a web
page. The call to the loading routine returned immediately, before the
page finished loading. My trace showed that "DocumentComplete" was
never called at all.

Here is the code in "waitForDocumentComplete":

Private Function waitForDocumentComplete() As Boolean
Dim before As Single, after As Single
Debug.Print "On entry to waitForDocumentComplete, explorerWait =",
explorerWait
before = Timer
Do While explorerWait
after = Timer
Debug.Print " 2. explorerWait =", explorerWait
If after < before Then before = before - 24 * 60 * 60 ' 'round
Midnight
Debug.Print " 3. explorerWait =", explorerWait
If after - before > pageLoadTimeout Then
MsgBox "Browser timed out loading page " +
explorerObject.Document.url, vbOKOnly
waitForDocumentComplete = False
Exit Function
End If
Debug.Print " 4. explorerWait =", explorerWait
DoEvents

On Error Resume Next
Debug.Print " 5. explorerWait =", explorerWait
Debug.Print Me.explorerObject.Document.body.all.length, "'" +
Me.explorerObject.StatusText + "'", Me.explorerObject.Busy
If Me.explorerObject.Document.body.all.length > 0 And _
Me.explorerObject.StatusText = "Done" And _
Not Me.explorerObject.Busy Then
explorerWait = False
End If
Debug.Print " 6. explorerWait =", explorerWait
On Error GoTo 0
Loop
'Debug.Print ">" +
CStr(Me.explorerObject.Document.body.all.length) + "," +
Me.explorerObject.StatusText + "," + CStr(Me.explorerObject.Busy)
waitForDocumentComplete = True
End Function

It appears to me that there is no way this code could possibly display
"5. explorerWait = True" and then "6.explorerWait = False" without
displaying a line with three property values in between. But that is
exactly what happened -- reproducibly. I close and restarted Word in
case some error was messing up the interpreter's state; it made no
difference. If I wait at a breakpoint until the page finishes loading
before calling waitForDocumentComplete, the code functions as it
should.

My mail address is jsachs177 at earthlink dot net.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top