Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using VBA to navigate web page/ maniuplate IE via Access

Hello StackOverflow community,

I have a question about using Access VBA to manipulate IE.

Essentially, I am trying to write code that will open a specific webpage using IE, search that page for a particular link (the name of the target link will depend on the circumstances of the user), navigate to a new page by programmatically clicking that link, and then repeating the process by looking for a specific link/element on the resulting new page.

The display text for the ultimate target link will always be the same, but the page that it resides on will be different in every case.

My issue is with programmatically searching the second-level page for the elements that reside there...my results keep giving me only elements from the first-level page, even after the browser has loaded the new link.

Apologies if I'm doing a poor job describing the context of the question so far.

My code, essentially, is as follows:

Dim ie As Object, ieDoc As HTMLDocument

Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True

strHTML = "http://targetsite.com/first-level_page"

ie.navigate strHTML

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend


'define first-level target link and search for it and then "click" it

Dim i As Integer
Dim txt As String, link As String, p As String

Set ieDoc = ie.Document

txt = "First-Level Target"
    Do Until link = txt Or i >= 1000
    i = i + 1
    link = ieDoc.Links(i).outerText
Loop

'I know the above loop is not exactly ideal in its current form, but it does give me a working first attempt at the functionality I'm trying to build.    

ieDoc.Links(i).Click

So far, so good. The code above works just as intended. It navigates correctly to the desired second-level page in all cases. Where I'm going wrong is when I try to search that second-level page for the final target element:

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend

'Search for final target element (which always has the same name and anchor text on all second-level pages)
ieDoc.getElementsByName("final-target-name").Item.Click

The line above (based on .getElementsByName) works just fine if I try to use it on the first-level page. But it does nothing once I've navigated to any second-level page. I've also tried to replace it with a modified version of the loop above that searches for the link on the first-level page. Same result.

As a troubleshooting step, I've also replaced that line with a debug.print command to simply name all of the elements on the second-level page, and this always returns the element names from the first page instead.

I assume it's clear that I'm somehow failing to correctly update or redefine my HTMLdocument after I've followed the first link. I've setting ieDoc as nothing and then re-setting it as ie.document, but that doesn't work either.

Hopefully there is a simple command or syntax that I'm simply ignorant to. But for the life of me I havent been able to have VBA correctly refer to the HTML elements existing on the page after the first link is clicked.

Thanks in advance for any advice!

~JQN

like image 262
John Q. Noob Avatar asked Oct 31 '22 06:10

John Q. Noob


1 Answers

You need to use a combination of @Matteo NNZ and @TimWilliams

If you know the "id" name of the element its easier to use getElementsByName("target").

if you don't know the "id" then loop anchor elements and search for the correct text. This narrows down to only Link or elements.

Set Anchors = IeDoc.getElementsByTagName("a")

then loop comparing .outertext or whatever sub field you need.

@TimWilliams: You need to load the found URL then set the newly loaded IeDoc inside the loop. Set the "ie" object to the new "ie" loaded page otherwise the 'ie' object will correctly remain the first page loaded. When you find your link you need to load the new page as you have already done.

'' throw away the first page loaded.
ie = nothing 
IeDoc = nothing

'' Set the new page loaded.
ie.navigate newHTML

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend

Set IeDoc = ie.Document

Repeat the process as above for the second page

Here are some other resources about 'parsing HTML in vba': http://www.ozgrid.com/forum/showthread.php?t=184695 Parse HTML content in VBA

like image 63
durbo Avatar answered Nov 12 '22 18:11

durbo