Write in an HTML input field using Excel VBA - excel

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.

Related

Automating a Report: Selecting from a drop down in IE using VBA

I'm trying to automate a report of mine using VBA. I was able to do the log in part and all but when it comes to navigating the next webpage with drop downs I can't seem to get a hold of it. I tried multiple ways to fill out the first drop down which is the report type and I can't find the correct code
All commented "'" are all the codes I've tried. I can't post the website since it's a client website.
html "inspect elemet" photo
Sub Get_RawFile()
Dim IE As New InternetExplorer
Dim HTMLDoc As HTMLDocument
Dim addressInput As HTMLInputElement
With IE
.Visible = True
.Navigate ("------------------------")
While IE.Busy Or IE.readyState <> 4: DoEvents: Wend
Set HTMLDoc = IE.document
HTMLDoc.all.UserName.Value = Sheets("Data Dump").Range("A1").Value
HTMLDoc.all.Password.Value = Sheets("Data Dump").Range("B1").Value
HTMLDoc.getElementById("login-btn").Click
While IE.Busy Or IE.readyState <> 4: DoEvents: Wend
'HTMLDoc.getElementByName("ddlReportType")(0).Value = "1"
'Set HTMLDoc = IE.document
'Set evtChange = HTMLDoc.createEvent("HTMLEvents")
'evtChange.initEvent "change", True, False
'Set selectElement = HTMLDoc.getElementById("ddlReportType")
'selectElement.Value = "1" 'Attendance
'selectElement.dispatchEvent evtChange
'Set htmlSelectElem = HTMLDoc.getElementsByTagName("ddlReportType")
'htmlSelectElem.selectedIndex = 1
'Set reporttype = IE.document.getElementById("ddlReportType")
'For i = 1 To reporttype.Options.Length
'If reporttype.Options(i).Text = "Attendance" Then
'reporttype.selectedIndex = i
'Exit For
'End If
'Next i
End With
Run-time error '438'
Object doesn't support this property or method
This method .getElementByName does not exist. It should be .getElementsByName("Something"), in which case the method returns a collection of elements whose Name attribute is Something.
The following would access the first element of the collection of elements whose Name attribute is ddlReportType and set its value to 1:
HTMLDoc.getElementsByName("ddlReportType")(0).Value = "1"
Having said that, you don't seem so sure as to what ddlReportType is.
If it's the id of an element then the element should look like so:
<tagName id="ddlReportType">Something</tagName>
In that case you should use the method .getElementByID()
If it's the Name of an element then the element should look like so:
<tagName Name="ddlReportType">Something</tagName>
In that case you should use the method .getElementsByName(), which returns a collection of elements.
If it's the Class of an element then the element should look like so:
<tagName Class="ddlReportType">Something</tagName>
In that case you should use the method .getElementsByClassName(), which returns a collection of elements.
Finally, I can tell you for sure that it's not a Tag Name so you definitely shouldn't use the .getElementsByTagName method.
EDIT
From the image you provided after editing your original post, it is clear that ddlReportType is the id of a <select></select> element. So you should do it this way:
Dim HTMLselect As HTMLSelectElement
Set HTMLselect = HTMLDoc.getElementById("ddlReportType")
HTMLselect.Value = "1"
References used: Microsoft HTML Object Library (VBE>Tools>References>...)
That's how to select one of the drop down options. To navigate further you would have to press some button I presume.

Cannot perform auto search on a specific website

Recently I am learning to use excel macro to search on a website. I've read several forum threads and I came up with the code below. However, error appears when I reach the row
SearchBox(0).Value = SearchString
I tried to remove the (0) but another error appears as well. The code works well on other websites. How should I change them to adapt to this site?
P.S. I would also like to know the way to click the search button.
Sub Searchstockcode()
Dim SearchString As String
SearchString = "700"
Set ie = CreateObject("InternetExplorer.Application")
With ie
ie.Visible = True
End With
ie.Navigate "http://www.hkexnews.hk/listedco/listconews/advancedsearch/search_active_main.aspx"
While ie.ReadyState <> 4
DoEvents
Wend
Dim SearchBox As Object
Set SearchBox = ie.Document.GetElementsByName("ct100$txt_stock_code")
SearchBox(0).Value = SearchString
Dim SearchButton As Object
Set SearchButton = ie.Document.GetElementsByName
End Sub
I don't know whether the problem with your name selection is due to the element having two name attributes but that seems possible.
You may use the following.
For the search box I use its id to target the element. This is normally unique on a document and the fastest selector method.
For the search button I use a CSS attribute + value selector of
[src*='/image/search.gif']
This targets the src attribute [] of the element by its value. * means contains. The selector looks for a src attribute containing /image/search.gif in its value.
You can observe the attribute here:
Option Explicit
Sub Searchstockcode()
Dim SearchString As String, SearchBox As Object, SearchButton As Object, ie As Object
SearchString = "700"
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.navigate "http://www.hkexnews.hk/listedco/listconews/advancedsearch/search_active_main.aspx"
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Set SearchBox = ie.document.getElementById("ctl00_txt_stock_code")
SearchBox.Value = SearchString
Set SearchButton = ie.document.querySelector("[src*='/image/search.gif']")
SearchButton.Click
While ie.Busy Or ie.readyState < 4: DoEvents: Wend
Stop '<==Delete me
'other code
ie.Quit
End Sub

Call a javascript function onclick using vba on a webpasge

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

VBA - IE automation - .getelements

I'm trying to enter text into an input field that has no ID. When I inspect the element I get this:
<input title="Affected Customer(s)" class="custom-input ng-pristine ng-invalid ng-invalid-required ng-touched" role="combobox" aria-expanded="false" aria-required="true" aria-owns="typeahead-78-1606" aria-autocomplete="list" required="" type="text" placeholder="Enter customer name, email, login ID or corporate ID" entity="incident" field-name="customer.loginId" potentially-required-field="" auto-focus="" typeahead="user as user.firstName + ' ' + user.lastName for user in getList('person', $viewValue)" typeahead-loading="person.isLoading" typeahead-wait-ms="500" typeahead-on-select="onCustomerSelect($model)" typeahead-template-url="views/create/custom-add-user-dropdown.html" typeahead-min-length="3" prevent-click-event="" ng-model="person.ngModel">
how do I reference this input field? I have tried many ways but they all fail. I think my understanding is lacking and hopefully a bit of help will get me on the right track. The code I have now that tries to locate this input field is:
Sub Automate_IE_Load_Page()
'This will load a webpage in IE
Dim i As Long
Dim URL As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim aEle As HTMLLinkElement 'special object variable for an <a> (link) element
'Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
'Set IE.Visible = True to make IE visible, or False for IE to run in the background
IE.Visible = True
'Define URL
URL = "https://ewpg-app-1041.hydro.mb.ca/ux/smart-it/#/create/incident"
'Navigate to URL
IE.navigate URL
' Wait while IE loading...
'IE ReadyState = 4 signifies the webpage has loaded (the first loop is set to avoid inadvertently skipping over the second loop)
Do While IE.readyState = 4: DoEvents: Loop 'Do While
Do Until IE.readyState = 4: DoEvents: Loop 'Do Until
objIE.Document.getElementsByName("customer.loginId")(0).Value = "test"
'click create new
'for each <a> element in the collection of objects with class of 'result__a'...
For Each aEle In objIE.Document.getElementsByName("Affected Customer(s)")
'...get the href link and print it to the sheet in col C, row y
result = aEle
'repeat times the # of ele's we have in the collection
Next
'Unload IE
Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing
End Sub
The line "objIE.Document.getElementsByName("customer.loginId")(0).Value = "test"" gives me the error Run-time error 424 - object expected.
Thank you for any help you can provide, this will probably be extremely easy but I'm just not understanding something basic obviously. The code above was taken from a various sites, seems to work fine. I had the for look working for testing using different logic.
Try Below Code instead :
getElementsByClassName("custom-input ng-pristine ng-invalid ng-invalid-required ng-touched")

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