Reputation: 23
Generally, what is the easiest way to wait for a pop-up window in VBA using the IE automation? I wrote a program with the help of this community, which has been very informative, every time that I hit a roadblock in my code. Thank you, graciously.
Situation:
I create a program that interacts with IE. It's an automation process that handles data based on the functionality of the site. In the automation process, when I click on a link, it opens a pop-up window. Here is where the problems being. Sometimes, the pop-window takes anywhere between 5 seconds to 30 seconds to load. However, I am unable to determine the length of time that it takes for the pop-window to load, nor does the program, which crashes every time it reaches outside the scope of the waiting period I set it for in the program.
Everything else works perfectly, except for this small little delete that is the ultimate death of my program and sends it spiraling downhill.
The pop-window has to load first before I am able to assign the popWindow (IE) object.
Dim popWindow As InternetExplorer
Set popWindow = oGetIEWindowFromTitle("Site Name")
Set deviceWindow = popWindow.Document
Function oGetIEWindowFromTitle(sTitle As String, _
Optional bCaseSensitive As Boolean = False, _
Optional bExact As Boolean = False) As Shdocvw.InternetExplorer
Dim objShellWindows As New Shdocvw.ShellWindows
Dim found As Boolean
Dim startTime As Single
found = False
'Loop through shell windows
For Each oGetIEWindowFromTitle In objShellWindows
found = oGetIEWindowFromTitleHandler(oGetIEWindowFromTitle, sTitle, bCaseSensitive, bExact)
If found Then Exit For
Next
'Check whether a window was found
If Not found Then
Set oGetIEWindowFromTitle = Nothing
Else
Do While oGetIEWindowFromTitle.Busy '----- this is what I have tried
Application.Wait (Now + TimeValue("00:00:01"))
Loop
Do While oGetIEWindowFromTitle.Busy = True Or oGetIEWindowFromTitle.ReadyState <> 4: DoEvents: Loop '------ this is what I have tried
End If
End Function
Private Function oGetIEWindowFromTitleHandler(win As Shdocvw.InternetExplorer, _
sTitle As String, _
bCaseSensitive As Boolean, _
bExact As Boolean) As Boolean
oGetIEWindowFromTitleHandler = False
On Error GoTo handler
'If the document is of type HTMLDocument, it is an IE window
If TypeName(win.Document) = "HTMLDocument" Then
'Check whether the title contains the passed title
If bExact Then
If (win.Document.Title = sTitle) Or ((Not bCaseSensitive) And (LCase(sTitle) = LCase(win.Document.Title))) Then oGetIEWindowFromTitleHandler = True
Else
If InStr(1, win.Document.Title, sTitle) Or ((Not bCaseSensitive) And (InStr(1, LCase(win.Document.Title), LCase(sTitle), vbTextCompare) <> 0)) Then oGetIEWindowFromTitleHandler = True
End If
End If
handler:
'We assume here that if an error is raised it's because
'the window is not of the correct type. Therefore we
'simply ignore it and carry on.
End Function
Upvotes: 1
Views: 695
Reputation: 166156
Here's one way to do it:
Sub Tester()
Dim w As Object, t
t = Timer
Set w = WaitForWindow("google.com", 10)
If Not w Is Nothing Then
Debug.Print "Found in " & Timer - t
Else
Debug.Print "Not found after " & Timer - t
End If
End Sub
'Find (or wait for) an IE window with location
' matching URL (using "Like" for matching)
'Try for maxWait seconds then give up
Function WaitForWindow(URL As String, maxWait As Long)
Dim rv As Object, t
t = Timer
Do While Timer - t < maxWait
Set rv = GetIEByUrl(URL)
If Not rv Is Nothing Then Exit Do
Application.Wait (Now + TimeValue("00:00:01"))
Loop
Set WaitForWindow = rv
End Function
'Try to get an existing IE window based on URL match
Function GetIEByUrl(URL As String) As Object
Dim o As Object, rv As Object
For Each o In CreateObject("Shell.Application").Windows
If TypeName(o) = "IWebBrowser2" Then
If o.Locationurl Like "*" & URL & "*" Then
Set rv = o
Exit For
End If
End If
Next o
Set GetIEByUrl = rv
End Function
Upvotes: 1