-
using .getElementsByName
Hey all,
i'm making a small tool to pass some data from my main form to a webpage (basically a ticket #) search for it open it (click it) & close it with provided comments, i'm using getElementByID to fetch the data from webpage & then provide necessary action (eg. send a click, set a value in textbox / combo box etc.). The problem is, when i search for the request it's "ElementID" is different as per the tkt # & hence i cannot hardcode it like the other stuff to "click" this tkt number. After some R&D i found another method : .getElementsByName but not sure how do i use it .
I'm basically stuck @ 2 things :
1. how do i get the value by GetElementsByName
2. after i get the value how do i find its "elementid" based on it's Name
My Code so far:
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim ResComm, SLAComm, FetchReq As String
ResComm = txtResComm.Text
SLAComm = txtSLAComm.Text
Dim ie
ie = CreateObject("InternetExplorer.Application")
'Url = TextBox3.Text
ie.Visible = True
ie.Navigate("http://myurl.com")
Wait(ie)
With ie.Document
.getElementByID("ctl00$ContentPlaceHolder1$txtSrNumber").value = Me.txtRCNum.Text 'pass ticket # to webpage
.getElementByID("ctl00$ContentPlaceHolder1$btn_search").click() ' click on search
Threading.Thread.Sleep(3000)
Wait(ie) 'wait till search page is loaded
'
Threading.Thread.Sleep(1500)
FetchReq = .GetElementsByName(txtRCNum.Text).ToString ' <--This is where i'm trying to get the tkt #
' click ticket # hyperlink
MsgBox("req# : " & FetchReq)
Threading.Thread.Sleep(1500)
Wait(ie) ' wait till request is opened
Threading.Thread.Sleep(1500) 'wait till all request status options are fetched
.getElementByID("ctl00_ContentPlaceHolder1_ddlmacd_status").focus() 'set focus to request status drop down box
SendKeys.Send("CC") 'Twice C is for complete
Wait(ie)
'Threading.Thread.Sleep(1000)
SendKeys.Send("^A")
SendKeys.Send("{Del}")
SendKeys.Send(ResComm)
End With
End Sub
Sub Wait(ByVal IE)
'WScript = CreateObject("WScript.Shell")
Do
Threading.Thread.Sleep(500)
Loop While IE.ReadyState < 4 And IE.Busy
Do
Threading.Thread.Sleep(500)
Loop While IE.ReadyState < 4 And IE.Busy
End Sub
-
Re: using .getElementsByName
nobody ???
pls pls i'm close to completing this...
i just need to know how do i use getElementsByName & send a click to it
or
simply i need to know how do i user getelementbyid for a changing element id ?
-
Re: using .getElementsByName
Hmmm
vb Code:
WebBrowser1.Document.All("elementname").InvokeMember("click")
I know that worked for another thread I was helping with using the element name so it might work here.
-
Re: using .getElementsByName
Still no luck :(
i'm getting this error :
The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))
-
Re: using .getElementsByName
can you show us the html?
getElementsByName returns an array, so if .GetElementsByName(txtRCNum.Text) is a uniquely named element, you'd use:
vb Code:
.GetElementsByName(txtRCNum.Text)(0).InnerText
-
Re: using .getElementsByName
GetElementByName works the same as GetElementByID... only it uses the NAME attribute instead of the ID attribute... So... if it has a NAME attribute, it'll work... otherwise, it may not.
To get an element, be it by ID or NAme... you need to know what value you are looking for.
-tg
-
Re: using .getElementsByName
ok, i used below & it returned me "system_#" !!! ???
Code:
FetchReq = ie.document.GetElementsByName(txtRCNum.Text).ToString
also here is the html code of the link i'm trying to click :
Code:
<a id="ctl00_ContentPlaceHolder1_requestNumber_9746128"
class="InboxColumnLinkDetail"
href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$requestNumber_9746128','')">8620410-6</a>
out of above "8620410-6" is the only info i have i do not have the "ID" since it changes everytime
-
Re: using .getElementsByName
if it changes every time, you can not use GetElementsByName. you will have to loop through the Document for each object (or object with tag name "a", or all links in the Document), and then check the object's ID, and use regex to match the ID, then get/set the value.
-
Re: using .getElementsByName
can't i use "8620410-6" (highligted below in HTML code) that is the only info i have & is displayed as hyperlink on search results page, but it's "elementid" is different
Code:
<a id="ctl00_ContentPlaceHolder1_requestNumber_9746128"
class="InboxColumnLinkDetail"
href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$requestNumber_9746128','')">8620410-6</a>
-
Re: using .getElementsByName
Well the "8620410-6" looks like the inner-text or perhaps the value of the element in question, so try doing what others have suggested and loop through the document for elements with tagname "a" then compare their inner-text to "8620410-6" and if true, you now have the element. This is assuming "8620410-6" is static.
-
Re: using .getElementsByName
cool, thx for that, cud u pls gimme overview of how that loop will look like ? i've never worked on html via vb .net before?
-
Re: using .getElementsByName
Umm I had to do something like this earlier today so I hope this will also work for you.
vb Code:
For each elem As HtmlElement in WebBrowser1.Document.GetElementsByTagName("a")
If elem.InnerText = "8620410-6" Then
'//do something
Exit For
End if
Next
Something like that I would stab a guess at.
-
Re: using .getElementsByName
bummer... it gave me below error :
Unable to cast COM object of type 'mshtml.HTMLAnchorElementClass' to class type 'System.Windows.Forms.HtmlElement'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
-
Re: using .getElementsByName
Uhhh, could show me what your current code looks like?
-
Re: using .getElementsByName
this just hit me... can i use the "getelementsbyclass" that is constant in the html code above....
btw, here's the loop code :
'For Each elem As HtmlElement In ie.Document.GetElementsByTagName("a")
If elem.InnerText = txtRCNum.Text Then
FetchReq = .getElementByID(elem.InnerText)
MsgBox("req # : " & FetchReq)
Exit For
End If
Next
-
Re: using .getElementsByName
the problem is that you're attempting to use members of HtmlDocument with a mshtml.IHtmlDocument2.
i'm not saying it's impossible, but i'd recommend you turn option strict on + cast objects explicitly.
-
Re: using .getElementsByName
Umm
vb.net Code:
'For Each elem As HtmlElement In ie.Document.GetElementsByTagName("a")
If elem.InnerText = txtRCNum.Text Then
FetchReq = .getElementByID(elem.InnerText)
MsgBox("req # : " & FetchReq)
Exit For
End If
Next
This won't work, I think you're misunderstanding the GetElementByID and InnerText properties in this case. InnerText is simply the text that the Element is holding, not an actual element. GetElementByID returns a HtmlElement. So By looping through all the htmlElements with the tag name "a", you've already got a htmlelement with the same behaviour. There is no need to attempt to "getelementbyID"
This line:
Code:
FetchReq = .getElementByID(elem.InnerText)
MsgBox("req # : " & FetchReq)
Exit For
End If
What you're trying to do is get an element by an ID that is the same as txtRCNum.Text (follow along the code logic and you'll see my point...in particular the "if elem.InnerText = txtRCNum.text")
I think you're over complicating things, if you've already got a unique htmlelement (which you have) all you need to do now is what you would do with the result of a GetElementByID
such as
Code:
elem.InvokeMember("click")
'...etc
-
Re: using .getElementsByName
yeah i think i'm freaking confused here & so close to pulling out my hair...
let me clarify this :
For Each elem As HtmlElement In ie.Document.GetElementsByTagName("a") 'Loop thru entire html page searching for all elements with tag "a"
If elem.InnerText = txtRCNum.Text Then ' within that if tag = "a" & it's inner text is txtrcnum then enter if loop
elem.InvokeMember("click") ' if condition is true click the element found
Exit For ' end for loop after the click is send
End If ' end if loop
Next
i hope so far so clear but when i run it i get following error on line # 1 (beginning of for loop):
Unable to cast COM object of type 'mshtml.HTMLAnchorElementClass' to class type 'System.Windows.Forms.HtmlElement'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
-
Re: using .getElementsByName
Well I'm lost, I wrote this exactly code up today for another project I was working on using tagnames to find elements and I never got invalid cast errors like that, what kind of object is "ie" I'm assuming it's a WebBrowser control?
-
Re: using .getElementsByName
Quote:
Originally Posted by
J-Deezy
Well I'm lost, I wrote this exactly code up today for another project I was working on using tagnames to find elements and I never got invalid cast errors like that, what kind of object is "ie" I'm assuming it's a WebBrowser control?
nope. it's a shdocvw.internetexplorer
-
Re: using .getElementsByName
/facepalm. God, the whole time I was assuming this was a standard webbrowser and was basing my code around that. My mistake. I think I'll withdraw from this thread.
-
Re: using .getElementsByName
@ .paul. : could u pls elaborate below ?
shdocvw.internetexplorer
-
Re: using .getElementsByName
Quote:
Originally Posted by
sk8er_boi
@ .paul. : could u pls elaborate below ?
shdocvw.internetexplorer
Wait if you're not using shdocw.internetexplorer...what type of control is "ie" in your form?
-
Re: using .getElementsByName
1st post:
Code:
Dim ie = CreateObject("InternetExplorer.Application")
I believe it uses shdocvw.internetexplorer underneath, so I'd try a standard WebBrowser control, unless you need more control, which you don't seem to.
-
Re: using .getElementsByName
Quote:
Originally Posted by
TTn
1st post:
Code:
Dim ie = CreateObject("InternetExplorer.Application")
I believe it uses shdocvw.internetexplorer underneath, so I'd try a standard WebBrowser control, unless you need more control, which you don't seem to.
Oops, must've missed that when I skimmed over it, my mistake. And yeah, I was going to suggest just simply crossing over to a WebBrowser control instead as it doesn't seem you actually need the interface (as you're manipulating the document "behind the scenes")
-
Re: using .getElementsByName
so how do i do it guys ??? pls pls little help here, this is the only thing stopping me from completing this tool, i've got the rest of code ready!
-
Re: using .getElementsByName
Go ahead and start by dropping a WebBrowser control onto your form.
You can use the toolbox, or dimension it like this:
Code:
Dim ie As New WebBrowser
-
Re: using .getElementsByName
hmmm..ok, wht if i add webbrowser control to my form itself ?, & then navigate within url (it's gonna be fixed anyway)
-
Re: using .getElementsByName
Yeah you can just add the webbrowser control to your form and set its visible property to false. If you use a webbrowser my above code will stop giving you COM errors :)
-
Re: using .getElementsByName
ok i've added WebBrowser control to my form, but it just won't wait till the page is loaded !!!
-
Re: using .getElementsByName
Put your fill code on the WebBrowser1_DocumentCompleted event :)
-
Re: using .getElementsByName
sorry forgot to mention .. this is wht i already did : (wbEURC is my webBrowser)
Code:
Private Sub wbEURC_DocumentComplete(ByVal pDisp As Object, ByVal URL As Object)
MsgBox("Web document is finished downloading")
With wbEURC.Document
.GetElementById("ctl00$ContentPlaceHolder1$txtSrNumber").InnerText = Me.txtRCNum.Text 'pass requst #
.GetElementById("ctl00$ContentPlaceHolder1$btn_search").RaiseEvent("Click")
' click on Go
End With
End Sub
-
Re: using .getElementsByName
It's not handling anything.
Private Sub wbEURC_DocumentComplete(ByVal pDisp As Object, ByVal URL As Object) Handles wbEURC.DocumentCompleted
that's what it should be.
-
Re: using .getElementsByName
your wbEURC_DocumentCompleted event will fire more than once while loading your webpage.
check wbEURC.readystate in the event
-
Re: using .getElementsByName
@J-Deezy : whan i add "handles wbEURC.DocumentCompleted" it gives me below error :
" Method 'Private Sub wbEURC_DocumentComplete(pDisp As Object, URL As Object)' cannot handle Event 'Public Event DocumentCompleted(sender As Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)' because they do not have the same signature "
-
Re: using .getElementsByName
@paul : is this correct ?
Code:
Private Sub wbEURC_DocumentComplete(ByVal pDisp As Object, ByVal URL As Object) Handles wbEURC.DocumentCompleted
If wbEURC.ReadyState = WebBrowserReadyState.Complete Then
MsgBox("Web document is finished downloading")
With wbEURC.Document
.GetElementById("ctl00$ContentPlaceHolder1$txtSrNumber").InnerText = Me.txtRCNum.Text 'pass requst #
'
.GetElementById("ctl00$ContentPlaceHolder1$btn_search").RaiseEvent("Click")
' click on Go
End With
End If
End Sub
-
Re: using .getElementsByName
.GetElementById("ctl00$ContentPlaceHolder1$btn_search").invokemember("Click")
-
Re: using .getElementsByName
Should look like this (different ByVals)
vb Code:
Private Sub wbEURC_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles wbEURC.DocumentCompleted
If wbEURC.ReadyState = WebBrowserReadyState.Complete Then
MsgBox("Web document is finished downloading")
With wbEURC.Document
.GetElementById("ctl00$ContentPlaceHolder1$txtSrNumber").InnerText = Me.txtRCNum.Text 'pass requst #
'
.GetElementById("ctl00$ContentPlaceHolder1$btn_search").RaiseEvent("Click")
' click on Go
End With
End If
End Sub
Does the contained code even work? I didn't think you could just change the inner text of an element, only the value.
-
Re: using .getElementsByName
Ok i've got till here...
open the page > insert the tkt # in search text box > click on "Go" (search) , i have inserted this code under wbEURC_documentcompleted event, i tried with a single tkt # & it bloody loops with single tkt # !!!
below is wht i'm using ....
Code:
Private Sub wbEURC_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles wbEURC.DocumentCompleted
If wbEURC.ReadyState = WebBrowserReadyState.Complete Then
stSbar.Text = ("Web document is finished downloading")
With wbEURC.Document
.GetElementById("ctl00$ContentPlaceHolder1$txtSrNumber").InnerText = Me.txtRCNum.Text 'pass requst #
.GetElementById("ctl00_ContentPlaceHolder1_btn_search").InvokeMember("click")' click on Go
End With
End If
End Sub
it just keeps searching the same tkt # over & over again ! how do i stopt it after 1st execution ?
-
Re: using .getElementsByName
Also is can some1 tell me wht is wrong with below code , i wrote this to freeze the execution till page is loaded :
Code:
Sub Wait(ByVal wbEURC)
While wbEURC.ReadyState = WebBrowserReadyState.Loading
Threading.Thread.Sleep(100)
End While
End Sub
OR
Code:
Sub Wait(ByVal wbEURC)
While wbEURC.ReadyState < 4
Threading.Thread.Sleep(100)
End While
End Sub
i simply need a fuction to pause the code till page is loaded with in the webbrowser control...