View Full Version : Solved: Controlling IE pop-ups via DHTML
stanl
07-18-2008, 12:03 PM
I have a web-scraping application that involves a setting where several controls are populated from a pop-up. Currently I use sendkeys to (1) select dropdown values (2) fill in TEXTAREAS (3) check/uncheck boxes (4) click the submit button.
Because of issues with simultaneous access to the underlying data the pop-up references, I would like a DHTML solution.
If have tried the VBS code below from both a .wsc and converting to VBA - the function accepts 2 parameters, (1) a newly instantiated IE Object (2) partial title of the popup window. The thought is the function either returns 0 or 1 [False/True] but I cannot get consistent results with the line oIE1 = obj
Has anyone used a method such as this to connect to a pop-up? :dunno Stan
function getpopup(oIE1,ttle)
Dim nvar,objShell
nvar=0
Set objShell = CreateObject("Shell.Application")
For Each obj In objShell.Windows
If TypeName(obj.Document) = "HTMLDocument" Then
text = obj.document.title
If InStr(1,text,ttle,1) Then
Set oIE1 = obj
nvar=1
Exit For
End if
End if
Next
Set objShell = Nothing
getpopup = nvar
end function
TomSchreiner
07-19-2008, 07:31 PM
Hi Stan.
A more dependable method using the IE new window event...
Paste this code in a module that will support WithEvents. Run it...
Option Explicit
'provide a reference to Microsoft Internet Controls
'if this is not an available option, browse for ieframe.dll in your sys folder
Private WithEvents ie As InternetExplorer
Private WithEvents iePopup As InternetExplorer
Sub Example()
Set ie = Nothing: Set iePopup = Nothing
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "http://mar.anomy.net/files/2004/02/popupdemo/"
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy
'provide a timeout here
DoEvents
Loop
'click the first anchor element
ie.Document.getElementsByTagName("A")(0).Click
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy And (Not iePopup Is Nothing)
'provide a timeout here
DoEvents
Loop
MsgBox "You now have a reference to the popup window. The locationURL = " & iePopup.LocationURL
End Sub
Private Sub ie_NewWindow2(ppDisp As Object, Cancel As Boolean)
Set iePopup = New InternetExplorer
Set ppDisp = iePopup
End Sub
stanl
07-20-2008, 03:58 AM
Paste this code in a module that will support WithEvents. Run it...
Thanks;
I think I need to have the code recognized as an 'object module', otherwise it errors out in the Private declarations. How do I accomplish this.
I can put the code in as a class module, but cannot call the sub, so do I need to initialize the class?
Stan
TomSchreiner
07-20-2008, 05:57 AM
Hi Stan. No need to instantiate it if you place it in a public class such as ThisWorkbook, one of your worksheets, or a custom class with its instancing property assigned with PublicNotCreatable. For example, if you place it in ThisWorkbook, you can call it directly like:
Call ThisWorkBook.Example
Download Example... (http://home.fuse.net/tstom/0720080851.www.vbaexpress.com.152541.zip)
stanl
07-20-2008, 07:18 AM
Thanks again;
downloaded and ran the workbook, and it was able to report the LocationURL. However, my real goal is to perform DHTML on the popup.
If I substitute
MsgBox "You now have a reference to the popup window. The locationURL = " & iePopup.LocationURL
which works
with
MsgBox "You now have a reference to the popup window. The HTML = " & iePopup.Document.InnerHTML
I get
TomSchreiner
07-20-2008, 08:43 AM
Hi Stan. The reference is there...
Option Explicit
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
'provide a reference to Microsoft Internet Controls
'if this is not an available option, browse for ieframe.dll in your sys folder
Private WithEvents ie As InternetExplorer
Private WithEvents iePopup As InternetExplorer
Sub Example()
Set ie = Nothing: Set iePopup = Nothing
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "http://mar.anomy.net/files/2004/02/popupdemo/"
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy
'provide a timeout here
DoEvents
Loop
'click the first anchor element
ie.Document.getelementsbytagname("A")(0).Click
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy And (Not iePopup Is Nothing)
'provide a timeout here
DoEvents
Loop
SetForegroundWindow Application.hwnd
' MsgBox "You now have a reference to the popup window. The locationURL = " & iePopup.LocationURL
'
' SetForegroundWindow ie.hwnd
' SetForegroundWindow iePopup.hwnd
Do Until iePopup.Document.ReadyState = "complete"
'provide a timeout here
DoEvents
Loop
MsgBox "You now have a reference to the popup window. The HTML = " & iePopup.Document.body.parentelement.InnerHTML
End Sub
Private Sub ie_NewWindow2(ppDisp As Object, Cancel As Boolean)
Set iePopup = New InternetExplorer
Set ppDisp = iePopup
End Sub
stanl
07-20-2008, 10:57 AM
Hi Stan. The reference is there...
Thanks
Stan
stanl
07-20-2008, 11:11 AM
I'm marking this thread close, but this is the sort of help that a good article could/should be written about.
I had previously tried document.ParentWindow rather than document.parentelement and kept getting Object Error messages -
Tom, it is obvious you have a great understanding of the IE object hierarchy - :clap: Stan
TomSchreiner
07-21-2008, 12:25 AM
Hi Stan. A big help is to early bind to MS HTML Object Library and use a more verbose syntax. Getting the benefit of intellisense with this extremely large library is must for me... Also, open your object browser and take a look at the typical offering for the run of the mill element. Select the HTMLGenericElement class and look at the list of properties and methods as compared to your average MSForms control. You can create some really spiffy userforms using HTML in a browser control.
Option Explicit
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
'provide a reference to Microsoft Internet Controls
'if this is not an available option, browse for ieframe.dll in your sys folder
'add a reference to Microsoft HTML Object Library as well :)
Private WithEvents ie As InternetExplorer
Private WithEvents iePopup As InternetExplorer
Sub Example()
Dim Doc As HTMLDocument
Dim Anchor As HTMLAnchorElement
Set ie = Nothing: Set iePopup = Nothing
Set ie = New InternetExplorer
ie.Visible = True
ie.Navigate "http://mar.anomy.net/files/2004/02/popupdemo/"
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy
'provide a timeout here
DoEvents
Loop
'click the first anchor element
Set Doc = ie.Document
Set Anchor = Doc.getElementsByTagName("A").Item(0)
Anchor.Click
Do Until ie.ReadyState = READYSTATE_COMPLETE And Not ie.Busy And (Not iePopup Is Nothing)
'provide a timeout here
DoEvents
Loop
SetForegroundWindow Application.hwnd
' MsgBox "You now have a reference to the popup window. The locationURL = " & iePopup.LocationURL
'
' SetForegroundWindow ie.hwnd
' SetForegroundWindow iePopup.hwnd
Do Until iePopup.Document.ReadyState = "complete"
'provide a timeout here
DoEvents
Loop
MsgBox "You now have a reference to the popup window. The HTML = " & iePopup.Document.body.parentelement.InnerHTML
End Sub
Private Sub ie_NewWindow2(ppDisp As Object, Cancel As Boolean)
Set iePopup = New InternetExplorer
Set ppDisp = iePopup
End Sub
stanl
07-21-2008, 11:30 AM
You are right on. I initialize my Object directly and found that
oIE = CreateObject("InternetExplorer.Application.1") is more reliable; and there are some interesting threads on how it differs from ("InternetExplorer.Application")
Stan
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.