Access To A Webpage's Frame Document Without Navigating To This Webpage
Solution 1:
Here my idea in code (this code is untested). First navigate to start page to login. Then find the main page. From the main page navigate to first frame and then to second. After that the dom element should contain the target button which can be now clicked. HTH
Option Explicit
' Add reference to Microsoft Internet Controls (SHDocVw)
' Add reference to Microsoft HTML Object Library
' Add reference to Microsoft Shall Controls And Automation
' e.g. http://192.168.51.52:9999/SomeApp/LoginPrivateConst StartUrl AsString = "Your start URL"' e.g. http://192.168.51.52:9999/SomeApp/Content
Private Const MainUrl As String = "Your main URL"
Sub ClickInsideOfFrame()
Dim ie As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
On Error GoTo error_handler
' Navigate to start page
Set ie = New SHDocVw.InternetExplorer
ie.Visible = True
ie.navigate StartUrl
WaitWhileBusy ie
' Enter user name and password and login
Login
'Switch to Main page
Set ie = IEWindowFromTitle(MainUrl)
Set doc = ie.document
' First find content frame and navige to url of this frame
NavigateToFrame ie, "frame[name='contentframe']"
' Find postfachcontent frame and navige to url of this frame next
NavigateToFrame ie, "frame[name='postfachcontent']"' Dom document should now contain the button which is inside of the
' postfachcontent frame
doc.querySelector("input[type='button'][name='some-button']").Click
error_handler:
If Err.Number <> 0 Then MsgBox Err.Description, vbCritical, "Error"
ie.Quit
Set ie = Nothing
End Sub
Private Sub WaitWhileBusy(ie As SHDocVw.InternetExplorer)
While ie.Busy Or ie.readyState <> READYSTATE_COMPLETE
DoEvents
Wend
End Sub
FunctionIEWindowFromTitle(sTitle AsString) AsSHDocVw.InternetExplorer
' ...
EndFunctionPrivateSubNavigateToFrame(ie As SHDocVw.InternetExplorer, selector AsString)
DimframeAsMSHTML.HTMLFrameElementDimdocAsMSHTML.HTMLDocumentSetdoc = ie.documentSetframe = doc.querySelector(selector)
IfNotframeIsNothingThenie.navigateMainUrl & frame.srcWaitWhileBusyieExitSubEndIfErr.RaisevbObjectError + 513, "NavigateToFrame", "Framenotfoundforselector '" & selector & "'."
EndSubPrivateSubLogin()
' ...
EndSub
Solution 2:
SOLUTION : For those it might interest, I found with the help of dee and the asnwer of Tim Williams on here a way to click on one of the multiple possible elements containing a "onclick" property.
For the greedy ones, here's the straight in-one-line solution which lists the clickable elements :
IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")
where IEDoc is the HTML document of the Main webpage.
Remarks :
In order to get this final solution, I had to do some tests to see which type I was dealing with to make sure I knew what I was doing. You can see these tests steps in the following code sample as well as their displayed result in the MsgBox in comment :
MsgBox TypeName(IEDoc.getElementsByName("contentframe")(0)) ' returns HTMLFrameElement MsgBox IEDoc.getElementsByName("contentframe")(0).document.getElementsByName("postfachcontent").Length ' 0 MsgBox IEDoc.frames(1).frames.Length ' returns 2 MsgBox TypeName(IEDoc.frames(1).frames(1)) ' HTMLWindow2 MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable")) ' HTMLDivElement MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").getElementsByName("result")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")) 'DispElementcollection MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById ("notPrintable").document.getElementsByName("result")(0)) ' HTMLFormElement MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).getElementsByClassName("resultRow")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByClassName("resultRow")) ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document) ' HTMLDocument Result_Form_Doc = IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document ' error IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).Click ' works...but no click MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("tr")) ' DispHTMLElementCollection MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("tr").Length ' 12...weird...I counted 2 IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.querySelector("td[onclick='cView(62972172,'0', viewButton, '' );']").Click ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.querySelector("td[onclick='cView(62972172,'0', viewButton, '' );']")) 'error MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").Length '42...counted 34 MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("table").Length ' 4...counted 1 IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")(30).Click ' WORKSSSSS MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").querySelectorAll("td[onclick='cView(62972172,'0', viewButton, '' );']").Length ' error MsgBox IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td").querySelectorAll("td[rowSpan='1']").Length ' error MsgBox TypeName(IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td")) ' DispHTMLElementCollectionDim Elem_td As IHTMLElement Dim el AsInteger, ind AsIntegerDim align_center_collection() el = 0 ind = 0ForEach Elem_td In IEDoc.frames(1).frames(1).document.getElementById("notPrintable").document.getElementsByName("result")(0).document.getElementsByTagName("td") el = el + 1If Elem_td.Align = "center"Then ind = ind + 1EndIfNext MsgBox el & " and " & ind ' if onclick : 42 and 0 (expected 34 and 16)' if rowspan : 42 and 42(expected 34 and 34)' if align = center : 42 and 2 (expected 34 and 2) - > good' if align = left : 42 and 14 (expected 34 and 14) - > good' if rowSpan : 42 and 42 (expected 34 and 34)
- I noticed that at some point the Intellisense of VBA won't help you anymore to know the available properties/methods so that's why I had to go through a few tests
- It seems impossible somehow to do all this step by step because even though the typename returns a valid type, I can't store this in a variable of that same type.
- I didn't select one exact element finally, but since (as you can see on the picture) there are a few clickable, I didn't do the "finition".
Post a Comment for "Access To A Webpage's Frame Document Without Navigating To This Webpage"