Call a javascript function onclick using vba on a webpasge - excel

Hi I'm trying to figure out a way to call a java script mapped to a button using VBA as part of the web page data entry automation.
Following is the code from the site and also the code that I'm working on.
Browser code :
<input name="reportIIS" value="Select" class="button" onclick="javascript: onSelect('/cooapp/servlet/CooMainServlet?command=SelectProgram&programType=IIS')" type="button">
VBA
Sub login() 'this is working
Const Url$ = "https://www.mast-technicalservices.com/ecp/index2.jsp"
Dim UserName As String, Password As String, LoginData As Workbook, elems As Object
UserName = ThisWorkbook.Sheets("Sheet1").Range("B1")
Password = ThisWorkbook.Sheets("Sheet1").Range("B2")
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.navigate Url
ieBusy ie
.Visible = True
Dim oLogin As Object, oPassword As Object
Set oLogin = .document.getElementsByName("ecp_param_userId")(0)
Set oPassword = .document.getElementsByName("ecp_param_password")(0)
oLogin.Value = UserName
oPassword.Value = Password
.document.forms(0).submit
ieBusy ie
Application.Wait (Now + TimeValue("0:00:02"))
' After 2sec wait time I need to click the said button to navigate to the next page
End With
End Sub
Sub ieBusy(ie As Object)
Do While ie.Busy Or ie.readyState < 4
DoEvents
Loop
End Sub

You might try using a CSS selector to select the target element. Then .fireEvent method on selected element using the event name.
CSS selector:
Select the element with selector
input[name='reportIIS']
Which means input tag with attribute name ="reportIIS"
So,
Dim elem As Object
Set elem = ie.document.querySelector("input[name='reportIIS']")
.fireEvent:
Then trigger the associated event with:
elem.fireEvent "onclick"
or
elem.fireEvent "onSelect"
It looks like it is the former.
More info on .fireEvent method:
fireEvent method: Fires a specified event on the object.
Syntax: object.fireEvent(bstrEventName, pvarEventObject,
pfCancelled)
It has a boolean return value which if TRUE tells you the event was successfully fired.
.querySelector method:
The Document method querySelector() returns the first Element
within the document that matches the specified selector, or group of
selectors. If no matches are found, null is returned.
Syntax: element = document.querySelector(selectors); <== note the
";" is not used in VBA

Related

Excel respond to a web DOM event via VBA

I am trying to respond to a button click on a website opened via Excel VBA.
The code below is trying to getting it working as a test with Duckduckgo.
The web page loads fine but I just cannot seem to get the onclick event, which I need to do to grab the values out of the text input elements that the user will have filled in.
Option Explicit
Private WithEvents IEButton As MSHTML.HTMLInputButtonElement
Public Sub Init(aButton As MSHTML.HTMLInputButtonElement)
Set IEButton = aButton
End Sub
Private Function IEButton_onclick() As Boolean
Debug.Print "Clicked"
MsgBox "HI"
End Function
Private Sub cmdTest_Click()
Dim ie As InternetExplorer, html As HTMLDocument
Dim link As String
link = "http://www.duckduckgo.com/"
Set ie = New InternetExplorer
With ie
.Visible = True
.navigate link
While .Busy = True Or .readyState < 4
DoEvents
Wend
Set html = .document
Dim ieBut As New clsIEButton
ieBut.Init html.querySelector("#search_button_homepage")
End With
ShowWindow ie.hwnd, SW_SHOWMAXIMIZED
End Sub
The web page loads fine but I just cannot seem to get the onclick
event, which I need to do to grab the values out of the text input
elements that the user will have filled in.
Please refer to the following sample code:
Private ieBut As clsIEButton 'global variable.
Private Sub cmdTest_Click()
Dim ie As InternetExplorer, html As HTMLDocument
Dim link As String
link = "http://www.duckduckgo.com/"
Set ie = New InternetExplorer
With ie
.Visible = True
.navigate link
While .Busy = True Or .readyState < 4
DoEvents
Wend
Set html = .document
Set ieBut = New clsIEButton
'transfer the button element and the html document.
ieBut.Init html.getElementById("search_button_homepage"), html
End With
End Sub
clsIEButton (class module)
Option Explicit
Private WithEvents IEButton As MSHTML.HTMLInputButtonElement
Private html As MSHTML.HTMLDocument
Private Function IEButton_onclick() As Boolean
Debug.Print "button: clicked!"
'based on the html document to get the entered value.
Debug.Print html.getElementById("search_form_input_homepage").Value
End Function
Public Sub Init(aButton As MSHTML.HTMLInputButtonElement, ahtml As MSHTML.HTMLDocument)
Set IEButton = aButton
Set html = ahtml
End Sub
After entering the value and click the search button, the VBA output looks as below:
As soon as cmdTest_Click completes, all its local variables are destroyed, including ieBut.
If you need that to hang around until someone clicks the button, you need to move
Dim ieBut As New clsIEButton
to the top of the module, outside of any Sub/Function.
Similar code here: detect event on IE from visio
Try this part
Set html = .document
html.queryselector("#search_form_input_homepage").Value = "Excel VBA"
html.queryselector("#search_button_homepage").Click
Put the following line before the action of the Cick
Range("A1").value = html.queryselector("#search_form_input_homepage").Value

how to enter value into website inputs by excel vba

I am trying to enter a value in a website filter, I can enter the username and password in login page by using the HTML element ID, after login I want to enter a value in filter input, the filter input id is units-grid-search-filter, but it automatically changed to units -grid -search -filter,
I don't the problem is in wherein element id space or delay
this is my code.
Sub Button3_Click()
On Error GoTo Err_Clear
sURL = "http://103.215.211.2/Web/Account/Login?ReturnUrl=%2fWeb%2f#25/-3/"
Set oBrowser = New InternetExplorer
oBrowser.Silent = True
oBrowser.timeout = 60
oBrowser.Navigate sURL
oBrowser.Visible = True
Do
' Wait till the Browser is loaded
Loop Until oBrowser.readyState = READYSTATE_COMPLETE
Set HTMLdoc = oBrowser.Document
HTMLdoc.all.UserName.Value = "abc"
HTMLdoc.all.Password.Value = "abc123"
HTMLdoc.all.units -grid - Search - Filter.Value = "123"
For Each oHTML_Element In HTMLdoc.getElementsByTagName("input")
Debug.Print oHTML_Element.Name
Next
Set frm = HTMLdoc.forms(0)
frm.submit
Set IE = CreateObject("InternetExplorer.Application")
' oBrowser.Refresh ' Refresh If Needed
Do Until Not IE.Busy And IE.readyState = 4
DoEvents
Loop
e.Click
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub
The site you are trying to automate is using knockoutjs.
The Textbox in which you are trying to set the value using your VBA code is set as observable in knockoutjs code.
If this parameter is an observable value, the binding will update the
element’s value whenever the value changes. If the parameter isn’t
observable, it will only set the element’s value once and will not
update it again later.
Whenever the user edits the value in the associated form control, KO
will update the property on your view model. KO will always attempt to
update your view model when the value has been modified and a user
transfers focus to another DOM node (i.e., on the change event), but
you can also trigger updates based on other events by using the
valueUpdate parameter described below.
Reference:
The "value" binding
Which means the value is coming from the knockoutjs model. If you modify the value manually then it will also modifies the value in model.
When you are trying to assign the value using your VBA code, no events occur and value not get updated to that model.
I tried to fire an event from VBA code. but it is not modifying the value in model. I tested with multiple JS events and it did not worked. If you try to pass the same event from your HTML code then it will give an error in VBA.
At last, I suggest you to make a test with Sendkeys.
Sendkeys is essentially the same as typing with the keyboard. You need to make sure the correct windows and objects are selecting before proceeding. Sendkeys can also trigger events that run based on user interaction on the web.
Sample code:
Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal HWND As Long) As Long
Sub demo()
Dim i As Long
Dim URL As String
Dim IE As Object
Dim HWNDSrc As Long
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "example.com"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
HWNDSrc = IE.HWND
SetForegroundWindow HWNDSrc
IE.Document.getElementById("abc").Focus
SendKeys "123", True
Set IE = Nothing
End Sub
Further, you can try to modify the code as per your requirement.

EXCEL VBA: Web Page Button Click

I have tried numerous variations of codes on this site to get my VBA to click on a button on a webpage and with the exception of one time have not been able to get any code to work. The one time was either a fluke or in an attempt to add the next step of the code I somehow inadvertently changed what was happening previously. Below is both the source code of the website and the code I'm using currently. Right now I do not get any errors, but instead of loading the next page when I include the button click code if just clears the form and stays on the present web page.
CODE:
Public Sub TestIE()
Dim IE As Object
Dim aNodeList As Object, i As Long
Dim bNodeList As Object, p As Long
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
' You can uncoment Next line To see form results
IE.Visible = False
' Send the form data To URL As POST binary request
IE.Navigate "https://pe.fanniemae.com/pe/pricing/search"
' Statusbar
Application.StatusBar = "Page is loading. Please wait..."
' Wait while IE loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
IE.Visible = True
Set aNodeList = IE.document.querySelectorAll("input[type=checkbox]")
If aNodeList Is Nothing Then Exit Sub
For i = 0 To 18
aNodeList.Item(i).Checked = True
Next i
'IE.document.querySelector("button[type=submit]").Click
Set bNodeList = IE.document.querySelectorAll("button[type=submit]")
If bNodeList Is Nothing Then Exit Sub
For p = 1 To 1
bNodeList.Item(p).Click
Next p
End Sub
Page Source:
<div class="row submit">
<button id="get-price" tabindex="3" type="submit" class="cell-right-
2">Get Prices</button>
<div class="pricing-error-message"></div>
When I inspect element on the button it does appear there is a clear form part of the code, which I would expect, but for whatever reason it is clearing the form instead of loading the new page. When I click on the button manually in IE it loads as expected.
Script that I believe is running:
<script type="text/javascript">
define('pageConf', function() {
return null || JSON.parse('{\"lastPricingFactors\":
{\"priceIncrement\":\"18\",\"priceView\":\"total\",\"executionType\
":\"Mandatory\",\"levelType\":\"Product\",\"remittanceType\":\"ActualActual
\",\"products\":\"160958\",\"1036FR\",\"102422\",\"163053\",\"160639\",\"
160058\",\"155509\",\"154232\",\"143846\",\"0005FR\",\"125331\",\"102301\",
\"114921\",\"115446\",\"144854\"],\"underwrittenWithDu\":false,\"
servicingReleased\":false,\"displayMarketFrozenMessage\":false,\"windows\":
[10,30,60,90],\"requestTimeMs\":1531424470700}}')
});
</script>
I was able to utilize a Select Case that inserted the criteria I wanted selected in the URL that was generated by the button vs. having to actually press the button which seems to be a working work around. Thanks for taking a look at this.

Write in an HTML input field using Excel VBA

I load an internet page and log in with myusername and mypassword using VBA.
I would like to write a search-term in an input field of the webpage using VBA.
Because there is no name and ID in the input field, I didn't succeed.
Here is my code :
Sub MyLogin()
Dim IE As InternetExplorer
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True
.navigate "https://www.example.com"
Do Until .readyState = 4
DoEvents
Loop
.document.all.Item("username").Value = "myusername"
.document.all.Item("password").Value = "mypassword"
.document.forms(0).submit
End With
Do Until IE.readyState = 4
DoEvents
Loop
Dim inputfield As HTMLInputElement
For Each inputfield In IE.document.getElementsByTagName("input")
If inputfield.Type = "text" Then inputfield.Value = "mysearch"
Next
Do Until IE.readyState = 4
DoEvents
Loop
End Sub
The HTML field I want to fill:
input class="input-inboxsearch form-control" type="text" value="" placeholder="Nom, email" maxlength="71"
How can I set the value of the input field?
Further to #Miqi180's comment, you can try replacing your the section of your code starting with Dim inputfield As HTMLInputElement with this:
Dim inputfield As Object
Set inputfield = IE.document.getElementsByClassName("input-inboxsearch form-control")
If inputfield.length > 0 Then
inputfield(0).Value = "mysearch"
End If
'carry on with your code
The getElementsByClassName method will return a collection so you have to check its length and then access the items of the collection. If there is only one element with that class then you can reference the 0th element of the collection.
I've set the inputfield variable as an Object because you appear to be using late binding.

Scraping on Amazon Prime Now postcode entry

I'm looking to enter a postcode on primenow.amazon.co.uk submit the form and paste the results into excel
Sub PostCode_Delivery_Short()
Dim ie As Object
Dim form As Variant, button As Variant
'add the “Microsoft Internet Controls” reference in your VBA Project indirectly
Set ie = CreateObject("InternetExplorer.Application")
'Input box for postcode
Postcode = InputBox("Enter Postcode")
With ie
.Visible = True
.Navigate ("primenow.amazon.co.uk")
'we ensure that the web page downloads completely before we fill the form automatically
Application.Wait (Now + TimeValue("00:00:04"))
'assigning the vinput variables to the html elements of the form
ie.Document.getElementsByClassName("availability__form__instructions__heading")(0).innertext = Postcode
'accessing the button via the form
Set form = ie.Document.getElementsByClassName("form")
Set button = form(0).onsubmit
form(0).submit
End With
'cleaning up memory
Set ie = Nothing
End Sub
What I'm struggling with is element ID (I think), I keep getting a runtime "error of Object variable or With block variable not set".
getElementsByName returns a collection, not a single element, so try something like:
ie.Document.getElementsByName("prime-now-input")(0).innertext = Postcode
EDIT Also:
.Document.getElementsByTagName("availability__form__instructions__heading")
I'm pretty sure there's no HTML element with that tag name ;-)
Maybe you meant getElementsByClassName() ?
EDIT2: this is the element where you need to input the postcode (using .Value, not .innerText)
<input type="text"
placeholder="Enter a postcode to see if we deliver to your area ..."
maxlength="9" data-reactid=".0.1.0.1.1.0.0.1.0.0">
My version of IE doesn't even render the input, so I can't offer more suggestions.
The website may have update and the below is for U.K. but it enters a postcode and presses the Shop Now (submit) button.
I use a CSS selector of input[type='submit'] to target the submit button. It reads as element(s) with input tag having type attribute with value 'submit'. The "[]" means attribute. Using the querySelector method to apply this selector will retrieve only the first match, as required.
Option Explicit
Public Sub SubmitPostCode()
Dim ie As New InternetExplorer
Const URL As String = "https://primenow.amazon.co.uk/onboard?sourceUrl=%2F"
Const POSTCODE As String = "WC1A 1DG"
With ie
.Visible = True
.navigate URL
While .Busy Or .readyState < 4: DoEvents: Wend
.document.getElementById("lsPostalCode").Value = POSTCODE
.document.querySelector("input[type='submit']").Click
While .Busy Or .readyState < 4: DoEvents: Wend
Stop '<== Delete me
.Quit
End With
End Sub

Resources