Reputation: 105
I am having some issues with a script that loads a website. Basically, it sucks at detecting when the site is completely loaded, and it then starts doing errors because it cant find the designated objects.
Is there a way, instead of using ie.readystate or ie.busy, to check if site is completely loaded? Maybe by something like a loop that checks if the object is there, before Setting it?
Like:
For Each wnd In CreateObject("Shell.Application").Windows
If InStr(1, wnd.FullName, "iexplore.exe", vbTextCompare) > 0 Then
Set IE = wnd
Exit For
End If
Next
IE.navigate2 "xxxx"
IE.Visible = 1
Do Until IE.document.getElementByID("username").Value = "xxxx"
Set Helem = IE.document.getElementByID("username")
Helem.Value = "xxxx"
Set Helem = IE.document.getElementByID("password")
Helem.Value = "xxxx"
Set Helem = IE.document.forms("signupForm")
Helem.Submit
Loop
ie.busy and ie.readystate (any combinaton) just seems very unstable when loading a form..
I could just use wscript.sleep to ensure the website is completely loaded, but that could be upwards of 10 seconds or more of wait between execution.
Any ideas? :)
Edit: As Requested:
One thing i have attempted, as someone claimed they had success doing that, is below:
Do while ie.readystate <> 4 wscript.sleep 200 Loop
Do while ie.busy wscript.sleep 200 Loop
Another is:
Do while ie.readystate <> 4 wscript.sleep 200 Loop
Do Until ie.readystate = 4 wscript.sleep 200 Loop
And ofcourse been trying them separately as well.
Issue is, once the site is flagged as loaded (readystate = 4) its not really 100% loaded. So when i try to do, for example:
Set Helem = IE.document.getElementByID("username")
Helem.Value = "xxxx"
Then i will get an error because it couldnt find the object.
Upvotes: 1
Views: 7314
Reputation: 360
The best method I was able to come up with so far is the code below. It relies on capturing the DocumentComplete event of Internet Explorer to detect when the page is fully loaded.
Features:
Enjoy :)
Option Explicit
'Sub Main
'--------
Dim DocumentComplete
Dim objIE : Set objIE = WScript.CreateObject("InternetExplorer.Application", "IE_")
objIE.Visible = True
If LoadPage("https://stackoverflow.com") Then
MsgBox "LoadPage completed."
Else
MsgBox "LoadPage timed out."
End If
Function LoadPage(ByVal strURL) 'As Boolean
'-------------------------------------------
Const TimeOut = 10 'Seconds
Dim StartTime : StartTime = Now()
DocumentComplete = False
objIE.Navigate strURL
Do While Not DocumentComplete
WScript.Sleep(1)
If DateDiff("s", StartTime, Now()) > TimeOut Then
LoadPage = False
Exit Function
End If
Loop
LoadPage = True
End Function 'LoadPage
Sub IE_DocumentComplete(pDisp, URL)
'-----------------------------------
' Fires when a document is completely loaded and initialized.
' https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768282(v=vs.85)
If (pDisp Is objIE) Then
DocumentComplete = True
End If
End Sub 'IE_DocumentComplete
Upvotes: 0
Reputation: 9299
In my experience, there are 3 ready states that you need to check.
and for it to be completely foolproof:
Here's a VBScript adaptation of a VBA sub that I've used for this task.
' web page load timeout in 10ths of a second
Const WAIT_TIMEOUT = 300
Const ERR_TIMEOUT = 1000
Const READYSTATE_COMPLETE = 4
Sub WaitUntilLoaded(ie)
Dim i, j, ready
' wait for page to connect
i = 0
Do Until ie.readyState = READYSTATE_COMPLETE
WScript.Sleep 100
i = i + 1
If i > WAIT_TIMEOUT Then
Err.Raise ERR_TIMEOUT, , "Timeout"
End If
Loop
' wait for document to load
Do Until ie.document.readyState = "complete"
WScript.Sleep 100
i = i + 1
If i > WAIT_TIMEOUT Then
Err.Raise ERR_TIMEOUT, , "Timeout"
End If
Loop
' wait for frames to load
Do
ready = True
For j = 0 To ie.document.frames.Length - 1
If ie.document.frames(j).document.readyState <> "complete" Then
ready = False
WScript.Sleep 100
i = i + 1
If i > WAIT_TIMEOUT Then
Err.Raise ERR_TIMEOUT, , "Timeout"
End If
End If
Next
Loop Until ready
End Sub
Upvotes: 2