I'm doing automation for a webpage. I just need to do a simple task (set a value on the page) but I cannot get it to work. Here's a cut from my code.
Dim IExp As SHDocVw.InternetExplorer
Dim hDoc As HTMLDocument
Dim hCol As MSHTML.IHTMLElementCollection
Dim hInp As MSHTML.HTMLInputElement
Dim hPoint As MSHTML.tagPOINT
Set IExp = New SHDocVw.InternetExplorer
IExp.Visible = True
IExp.navigate "http://somesite.com/"
Do Until IExp.Busy = False
DoEvents
Loop
Set hDoc = IExp.document
' Find the "search for" input box on the page
Set hCol = hDoc.getElementsByTagName("input")
For Each hInp In hCol
The code throws an exception at this line
Set HTMLdoc = iExp.Document
Error says:
Run-time error '-2147467259 (80004005)':
Automation error
Unspecified error
I just want it to throw a single string on the webpage.
Things that might help:
- Just need to run the htmldoc line without error
- By the way, im using IE9 and MS Excel 2010. I added vb.net tag as I know I could edit some syntax to get it to work with vba.
- I tried changing my references and the declared variables. I used MSXML2.XMLHTTP60, and also the code with CreateObject("InternetExplorer.Application") but they also don't work.
Thanks in advance guys!
Hmm I think the problem might be with what you have referenced, and the fact that you don't specify what library you are referencing HTMLDocument from:
Try changing
Dim hDoc As HTMLDocument
To:
Dim hDoc As MSHTML.HTMLDocument
If that sorts it out, make sure you don't have multiple libraries referenced that have a HTMLDocument object.
I just tested the code in Office 2013 referencing 'Microsoft Internet Controls' and 'Microsoft HTML Object Library' only and it worked fine for me.
Sure I have had a similar problem in the past when I had different XML libraries reference both using an xDocument object.
Related
Looking for help on how to implement VBA code to check if an element exists or explicitly waiting for it in VBA. Here is a small sample code I am testing out. The below code gives an error while running since it says "Object Required"
Dim Driver As New ChromeDriver
Driver.get "Test website"
If Driver.IsElementPresent(By.XPath("/html/body/div[2]/div/div[5]/h3"))) Then
Debug.Print("Yes")
Else
Debug.Print("No")
I even have tried changing the .IsElementPresent to this line of code so I can test the size of the element if it exists but receiving an error that "NoSuchElementError"
Debug.Print (browser.FindElementByXPath("/html/body/div[2]/div/div[5]/h3").Size())
Seem to work for me. The only issue I am seeing in your code is that you didn't declare By anywhere.
e.Start isn't a requirement, but I do it anyway.
So I would try declaring By and see what happen there. And you need to set it as a new instance, a simply type-declaration won't work, which means:
Just using Dim By As Selenium.By is NOT enough, but either of these lines:
Dim By As New Selenium.By
or
Dim By As Selenium.By
Set By = New Selenium.By
The Object Required error you are receiving is likely due to the missing declaration I stated above.
As text above, for me it worked like this...
Dim ch As Selenium.ChromeDriver
Set ch = New Selenium.ChromeDriver
'... all code ...
If ch.IsElementPresent(FindBy.XPath("//*[#id='div_footer']/table/tbody/tr/div")) Then
ch.FindElement(FindBy.XPath("//*[#id='div_footer']/table/tbody/tr/div")).Click
ElseIf ch.IsElementPresent(FindBy.XPath("//*[#id='xlsbutton']")) Then
ch.FindElement(FindBy.XPath("//*[#id='xlsbutton']")).Click
Else
'nohing here, only to understand stament
boolean_check_Download_Click_XYZ = false
End If
I wrote a code to parse some Web tables.
I get some web tables into an IHTMLElementCollection using Internet Explorer with this code:
TabWeb = IE.document.getelementsbytagname("table")
Then I use a sub who gets an object containing the IHTMLElementCollection and some other data:
Private Sub TblParsing(ByVal ArrVal() As Object)
Dim WTab As mshtml.IHTMLElementCollection = ArrVal(0)
'some code
End sub
My issue is: if I simply "call" this code, it works correctly:
Call TblParsing({WTab, LiRow})
but, if I try to run it into a threadpool:
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing), {WTab, LiRow})
the code fails and give me multiple
System.UnauthorizedAccessException
This happens on (each of) these code rows:
Rws = WTab(RifWT("Disc")).Rows.Length
If Not IsError(WTab(6).Cells(1).innertext) Then
Ogg_W = WTab(6).Cells(1).innertext
My goal is to navigate to another web page while my sub perform parsing.
I want to clarify that:
1) I've tryed to send the entire HTML to the sub and get it into a webbrowser but it didn't work because it isn't possible to cast from System.Windows.Forms.HtmlElementCollection to mshtml.IHTMLElementCollection (or I wasn't able to do it);
2) I can't use WebRequest and similar: I'm forced to use InternetExplorer;
3) I can't use System.Windows.Forms.HtmlElementCollection because my parsing code uses Cells, Rows and so on that are unavailable (and I don't want to rewrite all my parsing code)
EDIT:
Ok, I modified my code using answer hints as below:
'This in the caller sub
Dim IE As Object = CreateObject("internetexplorer.application")
'...some code
Dim IE_Body As String = IE.document.body.innerhtml
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {IE_Body, LiRow})
'...some code
'This is the called sub
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
'...some code
I get no errors but I'm not sure that it's all right because I tryed to use IE_Body string into webbrowser and it throws errors in the webpage (it shows a popup and I can ignore errors).
Am I using the right way to get Html from Internet Explorer into a string?
EDIT2:
I changed my code to:
Dim IE As New SHDocVw.InternetExplorer
'... some code
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(IE.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf TblParsing_2), {html, LiRow})
'... some code
Private Sub TblParsing_2(ByVal ArrVal() As Object)
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(ArrVal(0))
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim TabWeb As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
But I get an error PopUp like (I tryed to translate it):
Title:
Web page error
Text:
Debug this page?
This page contains errors that might prevent the proper display or function properly.
If you are not testing the web page, click No.
two checkboxes
do not show this message again
Use script debugger built-in Internet Explorer
It's the same error I got trying to get Html text into a WebBrowser.
But, If I could ignore this error, I think the code could work!
While the pop is showing I get error on
Dim domDoc As New mshtml.HTMLDocument
Error text translated is:
Retrieving the COM class factory for component with CLSID {25336920-03F9-11CF-8FD0-00AA00686F13} failed due to the following error: The 8,001,010th message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
Note that I've alredy set IE.silent = True
Edit: There was confusion as to what the OP meant by "Internet Explorer". I originally assumed that it meant the WinForm Webbrowser control; however the OP is creating the COM browser directly instead of using the .Net wrapper.
To get the browser document's defining HTML, you can cast the document against the mshtml.IHTMLDocument3 interface to expose the documentElement property.
Dim ie As New SHDocVw.InternetExplorer ' Proj COM Ref: Microsoft Internet Controls
ie.Navigate("some url")
' ... other stuff
Dim sourceIDoc3 As mshtml.IHTMLDocument3 = CType(ie.Document, mshtml.IHTMLDocument3)
Dim html As String = sourceIDoc3.documentElement.outerHTML
End Edit.
The following is based on my comment above. You use the WebBrowser.DocumentText property to create a mshtml.HTMLDocument.
Use this property when you want to manipulate the contents of an HTML page displayed in the WebBrowser control using string processing tools.
Once you extract this property as a String, there is no connection to the WebBrowser control and you can process the data in any thread you want.
Dim html As String = WebBrowser1.DocumentText
Dim domDoc As New mshtml.HTMLDocument
Dim domDoc2 As mshtml.IHTMLDocument2 = CType(domDoc, mshtml.IHTMLDocument2)
domDoc2.write(html)
Dim body As mshtml.IHTMLElement2 = CType(domDoc2.body, mshtml.IHTMLElement2)
Dim tables As mshtml.IHTMLElementCollection = body.getElementsByTagName("TABLE")
' ... do something
' cleanup COM objects
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(body)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(tables)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(domDoc2)
I am trying to use the following code to geocode a bunch of cities from this website: mygeoposition.com but there seems to be some sort of issue and the variable 'Lat' in the following code always returns empty:
Sub Code()
Dim IE As MSXML2.XMLHTTP60
Set IE = New MSXML2.XMLHTTP60
IE.Open "GET", "http://mygeoposition.com/?q=Chuo-ku, Osaka", False
IE.send
While IE.ReadyState <> 4
DoEvents
Wend
Dim HTMLDoc As MSHTML.HTMLDocument
Dim htmlBody As MSHTML.htmlBody
Set HTMLDoc = New MSHTML.HTMLDocument
Set htmlBody = HTMLDoc.body
htmlBody.innerHTML = IE.responseText
Lat = HTMLDoc.getElementById("geodata-lat").innerHTML
IE.abort
End Sub
I have another code that uses the browser to do the same thing and it works fine with that but it gets quite slow. When I use this code with MSXML, it just doesn't work. Apologies I am a newbie with using VBA for data extraction from website. Please help.
The response contains no content in the geodata-lat element. It appears that client side code is getting that data so your response only is looking at the html that the server generated. I tried this out myself and this is the section of the response you are looking for. You can see it is empty:
If you try an element that has content (geodata-kml-button), it does pull in a value ("Download KML file"). Ignore the ByteArrayToString() call, that was just me testing:
If they don't have a real API then I don't think you can get your data this way.
I am using the mshtml library inside a VB.NET console application to extract some data from an http request.
The code is as follows:
Dim htmlDocument As IHTMLDocument2
For i As Integer = 0 To 10
searchHtml = getHtml(url)
htmlDocument = New HTMLDocumentClass()
htmlDocument.write(searchHtml)
htmlDocument.close()
Dim results As IHTMLElement = htmlDocument.body.all.item("ires")
For Each li As IHTMLElement In results.all.tags("li")
Dim element As IHTMLElement = li.all.tags("cite")(0)
If element.innerText.ToLower().Contains(text) Then
' Do Something here
Exit For
End If
Next
Next
The code above is called recursively from another method.
I can run my code in debug and it works time after time with no problem.
If I compile the exe and run it then I receive one of two errors. Initially I got an "Object reference not set to an instance of an object" after 11 calls to the above. This is repeatable and always occurs after 11 iterations.
If I add a Threading.Thread.Sleep(1000) before the above and re-compile I get the "Access is denied" error, again after a certain number of iterations.
I've been trying to write some text into a textarea element of an aspnet form using the object internetexplorer.application in a macro using VBA
When I add a watch to the object after setting the "Value" attribute, i get the text that i am setting (using a MsgBox), but the browser doesnot seem to get the text when i submit it.
Im using IE 8.0.6001 and Office 2003.
Any help / comment will be very much appreciated.
Thanks
Sub Test2()
Dim Title As String
Dim Comments As String
Set wb = CreateObject("internetexplorer.application")
wb.navigate2 "http://tudrintra01/ads/Lists/Tasks1/NewForm.aspx?RootFolder=%2Fads%2FLists%2FTasks1&ContentTypeId=0x01030062FE73EDFA7DA644A27CE244EA983DA4&Source=http%3A%2F%2Ftudrintra01%2Fads%2FLists%2FTasks1%2FMyItems%2Easpx"
wb.Visible = True
Title = "TITULO PRUEBA"
Comments = COMENTARIO PRUEBA" '"Comentario"
Do Until wb.readyState = 4 ' wait for page to load
DoEvents
Loop
'Si el objeto es el Titulo del task
wb.Document.getElementByID("ctl00_m_g_c0644918_3730_4e2c_8434_7b760939e3d4_ctl00_ctl04_ctl00_ctl00_ctl00_ctl04_ctl00_ctl00_TextField").Value = Title
'Si el objeto es el Comment
wb.Document.getElementByID("ctl00_m_g_c0644918_3730_4e2c_8434_7b760939e3d4_ctl00_ctl04_ctl14_ctl00_ctl00_ctl04_ctl00_ctl00_TextField").Value = Comments
' Clean up
Set wb = Nothing
End Sub
You have not got an answer for days, so I comment on your question now. I successfully automated IE via the WebBrowser object, not via an Internetexplorer.Application object. Webbrowser will not open an IE application instance but just a "document window" in a Webbrowser control in a form in your Access application. So if you don't use Access or for some other reason this might not be a valuable hint for you.
This is not an answer to your question, that's why I waited some time to give my comment, but it's my best comment and I did everything possible with the DOM model through a wb object and never experienced a problem like yours that I could not solve. So you might want to try and rewrite your sub to using a Webbrowser.