Nice work with the control, Rob. Although your code could use some optimization. You can do more with the Document object model than you're doing now.
For starters, you shouldn't need the Sleep command while you're waiting. The ReadyState property will perform better than Busy.
VB Code:
Do While WebBrowser1.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
You don't have to focus the textbox in order to fill in the value or to click it. Calling the Click event on it is more reliable than using SendKeys.
VB Code:
hInp.Value = "07800008846"
hInp.Click
Finally, you don't have to use string manipulation to extract the data from the webpage. In this case, you could enumerate all TD tags with the getElementsByTagName method, then when the innerText property of a TD element is "Manufacurer", read out the next TD tag which contains text.
If you want to learn more about the Web Browser control or the Document Object Model, read the articles in my sig.
Thanks Vad. I just put this together last night quickly, first time.
I was having trouble with the .Click of the hInp object. Was stating a type mismatch or something.
ReadyState vs Busy, didnt see that one. getElementsByTagName was giving issues too because the submit
button doesnt have a id or name. What do you do in that case?
Thanks
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
Vader, I downloaded your browser control a long time ago, but didn't see anything in it that I saw as being able to parse information from web pages. Do you have an example of how you could programmatically interact with a page or series of web pages?
For instance, logging on to VBF and reading and or writing a Private message would be cool. And helpful. Any examples of automating would help.
a very informative thread ! like the way ya got the page on the form...
since i do this all the time for stock data i would add that using api URLDownloadToFile is prolly faster & no send keys needed...
VB Code:
Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Public Function DownloadFile(URL As String, LocalFilename As String) As Boolean
Well, I was just trying to find a common site that most of us could use. I don't know how that would be hacking, as long as it was your own account, but whatever. I'd be just as happy with any site that has log on credentials.
I've only seen one instance of this that actually worked.
'Add component to Microsoft HTML Object Library
'Add component Microsoft Internet Controls
'Add a command button (Command1)
'Add a web browser control to the form (WebBrowser1)
Dim hDoc 'As MSHTML.HTMLDocument
Dim hCol 'As MSHTML.IHTMLElementCollection
Dim hInp 'As MSHTML.HTMLInputElement
Dim hSub 'As MSHTML.HTMLInputButtonElement
Dim hTxt 'As MSHTML.HTMLInputTextElement
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Sub Command1_Click()
Dim iStart As Integer
Dim iEnd As Integer
iStart = 0
iEnd = 0
If WebBrowser1.LocationURL <> "http://www.upcdatabase.com/nocheckdigit.pl" Then
WebBrowser1.Navigate2 "http://www.upcdatabase.com/nocheckdigit.pl"
End If
Do While WebBrowser1.Busy = True
DoEvents
Sleep 500
Loop
Set hDoc = WebBrowser1.Document
Set hInp = hDoc.getElementById("upc")
hInp.focus
hInp.Value = "07800008846"
SendKeys "{ENTER}", True
Do While WebBrowser1.Busy = True
DoEvents
Sleep 500
Loop
Set hInp = Nothing
'Parse the elements and read the values of the data returned
'Set document variable = to the new results documents page
Set hDoc = WebBrowser1.Document
'Find the description:
iStart = InStr(1, hDoc.body.innerHTML, "<TD>Description</TD>") + 37
iEnd = InStr(iStart, hDoc.body.innerHTML, "</TD></TR>")
MsgBox Mid$(hDoc.body.innerHTML, iStart, iEnd - iStart)
'Find the Size/Weight:
iStart = InStr(iStart, hDoc.body.innerHTML, "<TD>Size/Weight</TD>") + 37
iEnd = InStr(iStart, hDoc.body.innerHTML, "</TD></TR>")
MsgBox Mid$(hDoc.body.innerHTML, iStart, iEnd - iStart)
'Find Manufacturer:
iStart = InStr(iStart, hDoc.body.innerHTML, "<TD>Manufacturer</TD>") + 38
iEnd = InStr(iStart, hDoc.body.innerHTML, "(<A href=")
MsgBox Mid$(hDoc.body.innerHTML, iStart, iEnd - iStart)
'Find the Entered/Modified:
iStart = InStr(iStart, hDoc.body.innerHTML, "<TD>Entered/Modified</TD>") + 42
iEnd = InStr(iStart, hDoc.body.innerHTML, "</TD></TR>")
MsgBox Mid$(hDoc.body.innerHTML, iStart, iEnd - iStart)
End Sub
Private Sub Form_Load()
WebBrowser1.Navigate2 "http://www.upcdatabase.com/nocheckdigit.pl"
End Sub
Private Sub Form_Resize()
If Me.WindowState <> vbMinimized Then
WebBrowser1.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight - 450 'Make adjustment for command button
End If
End Sub
Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
' Set hDoc = WebBrowser1.Document
End Sub
P.S. God Love You And Have A Good Day!!!My web page
Come on Bob, you got to give some effort and write at least one line of code.
You didnt even state if your getting an error or what you are wanting to do?
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
I tried his suggestions. The ready state fires too soon for the first messagebox, so I had to leave the sleep command in. I also couldn't get the .click to work either. Here is what I have to get them automatically.
And added the error trap in case you have an invalid number.
VB Code:
Private Sub Command1_Click()
Dim iStart As Integer
Dim iEnd As Integer
Dim UPC As String
iStart = 0
iEnd = 0
If WebBrowser1.LocationURL <> "http://www.upcdatabase.com/nocheckdigit.pl" Then
Attached is a sample project that completely relies on the Document Object Model to extract the info from the UPC site. It's much more reliable than string parsing, and needs fewer lines too. I'll write another example to play around with VBForums, David.
Bob, why do you attempt to write an application in a programming language you don't know and obviously do not want to learn? If you want an application written for you, hire a programmer at RentACoder.com. A forum is meant to help you with programming, not to deliver complete applications for free on demand...
using that, I still get an object or with block not set. I think the same thing was happening when I switched my example back to the sleep statement. The error is on the line that submits the upc number. If I hit F5, it runs, though.
That definitely seems like the correct way to do it. Thanks.
It happens because the loop is entered before the BeforeNavigate2 event has been reached. Try putting 'blnBusy = True' just before the loop; that should solve it.
Option Explicit
Dim UPC As String
Dim Document
Dim getElementsByTagName
Dim Item
Dim innerText
Dim a
Dim b
Dim c
Dim d
Dim f
Dim z
Dim blnBusy As Boolean
Private Sub Command1_Click()
Dim i As Integer
'Navigate to the page
WebBrowser1.Navigate2 "http://www.upcdatabase.com/nocheckdigit.pl"
'Both the readystate and the busy properties of the WB control
'are not completely reliable. The best way to wait for loading to take
'place I have found so far is using a custom boolean variable that
'is set in the BeforeNavigate2 and NavigateComplete2 events.
blnBusy = True
Do While blnBusy = True
DoEvents
Loop
'Fill in the upc number in the textbox with ID 'UPC'
'blnBusy = True
UPC = InputBox("Enter UPC Number", , "07800008846")
WebBrowser1.Document.getElementById("upc").Value = UPC
'Submit the first (and only) form in the page
WebBrowser1.Document.Forms.Item(0).submit
'Wait for the new page to load again
'blnBusy = True
Do While blnBusy = True
DoEvents
Loop
'Enumerate all TD tags in the document, because the info we want to extract
'is inside them.
For i = 0 To WebBrowser1.Document.getElementsByTagName("td").length - 1
Select Case WebBrowser1.Document.getElementsByTagName("td").Item(i).innerText
'If the text of the TD tag is one of the value names we're
'looking for, return the text in the second TD tag after it.
'As you can see in the source, all TD's with value names are
'followed by an empty TD tag and a TD tag containing the actual
'value. E.g. <td>Description</td><td></td><td>DR PEPPER CHER VAN 2LT</td>
Case "Description", "Size/Weight", "Manufacturer", "Entered/Modified"
MsgBox WebBrowser1.Document.getElementsByTagName("td").Item(i + 2).innerText
a = WebBrowser1.Document.getElementsByTagName("td").Item(i + 2).innerText
z = WebBrowser1
b = Document
c = getElementsByTagName
d = Item
f = innerText
Open "c:\pos\bob.dat" For Append As #1
Print #1, a,
Print #1, z, b, c, d, f
'Print #1, z,
'Print #1, b
'Print #1, c
'Print #1, d
'Print #1, f
'Print #1,
Close #1
End Select
Next i
End Sub
Private Sub Command2_Click()
Unload Me
End Sub
Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
blnBusy = True
End Sub
Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
blnBusy = False
End Sub
Can you all fix for me?
It print one line and does not enter to print the next upc on the next line.
P.S. God Love You And Have A Good Day!!!My web page
Come on Bob, you can do it!
I too was unaware of the capabilities of the Document object always parsed text myself.
Thanks for the great examples Vader.
This is a great thread.
I think this is the first step. It loads the page into the forms web browser. Then upon the command1 click
it will enter the upc into the web page's textbox and sends an enter keypress. Then the page returns
with the upc data.
VB Code:
Option Explicit
'Add component to Microsoft HTML Object Library
'Add component Microsoft Internet Controls
'Add a command button (Command1)
'Add a web browser control to the form (WebBrowser1)
Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
Set hDoc = WebBrowser1.Document
End Sub
Hi rob, i am very interesting on this question and naturally on you work...
I use Excel and VBA...
For you is possible to arrange this your code to put value from a column of sheet and put into a box present on this site and after press the button SUBMIT:
ok. I seem to have figured out the clicking part. I am now having a problem with submitting the info into the next textbox. I belive it's a problem with frames. I think the vb code is tring to paste the text in the first frame. this is not the correct frame.
Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
blnBusy = True
End Sub
Private Sub WebBrowser1_NavigateComplete2(ByVal pDisp As Object, URL As Variant)