IE11 Automation via Excel VBA - Forms - html

This is part 2 from my original post here. So now once logged in, I have to make two clicks to display the information I'm ultimately trying to scrape. I cannot seem to figure out the proper way to drill down to get to the clicks to work. It is all buried within a form. The 1st image shows the form structure. The 2nd image shows all of the code where I'm trying to get to the Current Situation link below the Supervisor span. I had to use the following (as you see from my previous post) to get IE to stay connected so not sure if that has any impact:
Dim objIE As Object
Set objIE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
In an attempt to automate the Current Situation tab click, I've tried the following with no luck (with and without the 0)
objIE.document.getElementById("1617")(0).Click
I'm more interested in getting educated in addition to getting an answer. Is there a method to drilling down into information within a form? I was under the impression that ALL the elements of a webpage were pulled in during loading. So is this not truly an element in my minimal understanding with webpage automation?
As a note, I do have to click Supervisor to get the tree below it to display. Thanks in advance for your help!
UPDATE:
Ok a major oversight here I think. Based on my previous post, the login functions perfectly. But once logged in, a new window gets created. So I believe that is the challenge, right? It can't find any of these IDs or Elements because it's looking at the original IE object, not the new window. So how do I get it to activate/access the new window? Sorry I missed that earlier!

Method getElementById returns a single element, not a collection, unlike for example getElementsByClassName (look at "Element" vs "Elements" in method name). Therefore (0) or any other index of collection should not be used.
Correct syntax is:
objIE.document.getElementById("1617").Click
For pop-up windows try this:
Dim wURL As String
Dim myWindow As Object
For Each myWindow In CreateObject("Shell.Application").Windows
wURL = myWindow.LocationURL
If InStr(wURL, "constant_part_of_popup_window_link") <> 0 Then
'do stuff
myWindow.Quit
Exit For
End if
Next myWindow
For accessing an element within iFrame:
myWindow.document.getElementById("frameMainMenu").contentWindow.document.getElementById("1617").Click

Related

Is there a way of accessing the second line of the dropdown list in vba?

I am currently working on a VBA project on a website. Here is a screenshot of the part of the website i am interested in.
I basically have to write a vba code that selects the second row of this dropdown list.
I wrote this piece of code
Dim i As Integer
Dim title As Variant
Set title = ie.getElementsByClassName("chosen-single")(3)
This code is actually refering to the correct part of the website because when i run these commands
MsgBox title.innerText
MsgBox title.innerHTML
I respectively get "Current" and the html of this part.
However, I am having trouble clicking on the second line of this dropdown menu. I do not want to access it by using the innerText "2019/07/31" because this date will constantly be changing. I just want to access the second element of the list always.
Can anyone help me with that?
Here is a snapshot of the HTML code of this webpage in case it helps:
Thank you so much!!

Textbox with reference to dropdown returns nothing

I have cmbCountry on a form as an unbound dropdown. The dropdown works as expected. I have setup a textbox called txtCM_ID on the same form, in which I want to display the ID that was selected in the dropdown.
When I enter the record source for the textbox as =Forms![frm_ClientModel]!cmbCountry.Column(0) access automatically changes it to read =[Forms]![frm_ClientModel]![cmbCountry].[column](0)
My version returns the correct information when i test it in the VBE Immediate window. The code that access produces returns the below when run in the Immediate window:
runtime error 450: Wrong number of arguments or invalid property
assignment
The frustrating thing is, that regardless of where or how i enter the code in the control source, access changes it to its version. When the form is opened the txtCM_ID simply remains blank.
I have also tried to go around this problem by changing my reference to the following: Forms("frm_ClientModel").Controls("cmbCountry").column(0)
While this version (also tested and ok in VBE) doesn't produce an error, it too returns nothing in the text box.
What am I missing / doing wrong / overlooking?
Use just
=[cmbCountry]
To access the value of cmbCountry from other control.
I was not able to specifically determine why this happened, but ended up solving the issue by using the OnClick Event of the Dropdown and writing the needed info into the Textbox via VBA with this:
Private Sub cmbCountry_AfterUpdate()
Me.txt_CMID = Forms("frm_ClientModel").Controls("cmbCountry").Column(0)
End Sub
If anyone else finds an answer as to why form controls did not work properly I would be interested in hearing from you.

Scrape/Retrieving data from website in <TD> tag with VBA

I know there are various questions relating to this topic, I have read them and because I am a novice developer I am unable to apply it to my specific situation, i.e after reading everything I still can't get it to work. So I will ask the question for my specific situation. Thanks for the help.
I am trying to work out the vba code to retrieve the data in the following html markup.
<td class='overview-last15'><strong>LAST 15:</strong>X6X0X17X1X011X3</td>
I want to extract the X6X0X17X1X011X3 part.
"Last 15" appears 10 times in the full html markup shown below, I want to extract the 15 characters for each one, start with extracting the first one.
I will include the link to the html page because the code is too long to post here. Please 'view source'.
https://www.ladbrokes.com.au/cache/formguides/formguide-2017-10-28-moonee valley-2.html
(hope the link works, I tried posting the code and it's too long!)
Thanks in advance
Here is the code I've tried so far
Sub testweb()
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Top = 0
objIE.Left = 0
objIE.Visible = True
On Error Resume Next
objIE.navigate ("https://www.ladbrokes.com.au/cache/formguides/formguide-2017-10-28-moonee%20valley-2.html")
Do
DoEvents
If Err.Number <> 0 Then
objIE.Quit
Set objIE = Nothing
GoTo mystart:
End If
Loop Until objIE.readystate = 4 ' 4 is complete
' I've tried all these lines
Dim myData, oHtml
'Set myDadta=oHtml.getElementById("myDiv").getElementsByClassName("overview-table")(0).getElementsByClassName("overview-last15")(0).innerText
'getElementsByTagName("Table")(0).getElementsByTagName("td")(1)
'Set myData = oHtml.getElementById("runner 1").getElementsByClassName("overview-table")(0).getElementsByClassName("title-entrant-name")(0).innerText
'Set myDada = oHtml.getElementByTitle("titlerunner-1").getElementsByClassName("overview-table")(0).getElementsByClassName("title-entrant-name")(0).innerText
MsgBox myData
' we quit the application Internet Explorer or close it
'objIE.Quit
End Sub
What I want to see is X6X0X17X1X011X3 instead I get msgbox with nothing.
I think you are asking for help on programming. Please understand this answer to be in response to such a request, even though it may not immediately solve your problem.
Start with Option Explicit at the top of your code. Then declare all your variables. Fight your way through the maze of what data type each one should be. Avoid the easy solution as much as the automatic ones. They are all too broad. The more precise you can define a data type the better you will understand it, the better you will be able to handle it. Saves a lot of time!
Now take this line of your code.
Set myDadta=oHtml.getElementById("myDiv").getElementsByClassName("overview-table")(0).getElementsByClassName
All the getElement functions return HTMLElements or IHTMLElements which have properties leading to the innerText or outerText properties which are strings. These strings you can analyse (read) and find out whether you have the correct one. Your above code example assigns the element of the element of the element to an object, and you can't easily find out whether you have the part of the page which contains the text you want to scrape, nor which other part of the site you happen to have caught hold of or which mistake you may have made.
When you look at the way MSDN teaches this subject you will find that they break up the code like this.
Dim myDiv as HTMLElement
Dim myClass As HTMLElement
Dim myData As HTMLElement ' you might have a type here "MyDadta"
Set myDiv = oHtml.getElementById("myDiv")
Set myClass = MyDiv.getElementsByClassName("overview-table")(0)
Set myData=myClass.getElementsByClassName
The point is that you are able to check, step by step, what exactly is contained in the element you have specified. After you are sure that you have the correct innerText you might well throw the elements together again in your final code. Frankly, I doubt that you would do that however. Next time the site has a change you may have to repeat your analysis, and then you would have to take everything apart again. Besides, more methodically built code is likely to be more stable. There is no evidence that your more compact code is actually better or runs even one thousandth of a second faster.
The final innerText which contains the string you are interested in is of data type string. You can simply use the Instr function to look for "strong>" and extract the characters before the next "<".

Auto-submit HTML Form using VB in Access 2007

I'm at my wit's end on this one.
Part of a project I'm working on requires interaction with an HTML form to bring up the correct page on an external web-based tool. I've managed to make this form accept entered variables and be generated on the fly using document.write, but what I haven't been able to do reliably is trigger the 'Submit' action in a way that will not throw off Error 91.
So far, I've been using a simple getelementbyid.click call... Here's a list of a few things I've tried to get it to trigger:
TestLoop:
Pause (1)
BrowserControl.document.getelementbyid("Submit").click
On Error Goto TestLoop
*(The 'Error Loop' tactic didn't really work at all.)
Pause (3)
BrowserControl.document.getelementbyid("Submit").click
(This actually works the best, but because different PCs might have different hardware specs and open applications that might slow it down, what works for me hasn't been working for another tester. If I make it TOO long, I end up adding additional delay to a form I'm already worried about being too slow.)
<script type="text/javascript">
window.onload = function(){
document.getElementById('Submit').click();;
}
</script>
(Embedding an auto-trigger in the generated HTML, frustratingly, works OUTSIDE of the embedded web browser control, but not inside it.)
Private Sub wb_NavigateComplete2(ByVal pDisp As Object, URL As Variant)
If Me.BrowserControl.Document.URL= "about:blank" Then
BrowserControl.document.getelementbyid("Submit").click
End If
End Sub
(For some insane reason, using debug.print I found that it's saying the navigation is complete before it's actually complete, so this didn't work at all.)
I may have missed a few... I've been attacking this from a bunch of different angles. The trick is that I have to use the HTML form to interact with this system that I don't have admin priveledges on, so changing how the information is recieved isn't really an option.
My last train of thought was to see if I could mimic a FORM submission using straight VB, bypassing the need for a 'click' event, but it's been exceptionally difficult to search for things related to HTML FORM interactions with Access 2007 Forms. :P
Any assistance would be greatly appreciated!
Well, after 7 months of testing and thousands of activations in that time, splitting the 'work' seems to have done the trick.
Form_Open: Initialises the Browser Object and sets its address to about:blank
Form_Current: Calls a formula that 'draws' the web form using Document.Write, then enters a loop...
TestLoop:
BrowserControl.document.getelementbyid("Submit").click
On Error Goto TestLoop

Run VBA code whenever a tabbed form is reselected in Access

EDIT: For clarification, I'm talking in the below post about tabbed document browsing, not a Tab Control. However, if you're looking for roughly the same problem but regarding a Tab Control, Gord Thompson's answer is correct. Two answers for the price of one!
I've got an Access 2007 database that uses tabbed documents. I need to run some VBA code every time a user selects the form called "Reports", either via opening it or clicking on its tab if it's already open.
I could achieve much the same thing by closing it each time it's used and running the code on an OnLoad event, but ideally I'd like to keep it open so that users can keep the settings of the various drop down boxes, radio boxes etc that they've already set on "Reports".
I was hoping for an event that could run code on tab reselection, but neither of my guesses (OnCurrent and GotFocus) seem to work (OnCurrent works only when the form is opened, like OnLoad would).
Any ideas greatly appreciated - can't find what I'm looking for on Google, though I suspect that's because I don't know exactly what I'm looking for.
The .Value property of a TabControl returns the index (zero-based) of the current page. So, if I have a TabControl named TabCtl14 that contains two pages, FirstPage and SecondPage, then the code...
Private Sub TabCtl14_Click()
If Me.TabCtl14.Value = 1 Then
MsgBox "SecondPage was clicked."
End If
End Sub
...displays the MsgBox whenever I click the "SecondPage" tab in the TabControl.
Have found the answer I was looking for. It's the OnActivate event.