IE Handling in Excel macros - excel

I am new to Excel macros and I am trying to auto-fill the text box and select the option from Dropdown and click on Submit.
Using macros I have navigated to a page and from the page, I need to enter the text in the text box, and based on the Suggestion, I need to select the option.
Once the option is selected I need to click on continue using macros.
Here is the current code (I tried with the commented line but it's not working).
Sub Create_Change()
Dim i As Long
Dim URL As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim HWNDSrc As Long
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
URL = "URL to Navigate"
IE.Navigate URL
Application.StatusBar = URL & " is loading. Please wait..."
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
Application.StatusBar = URL & " Loaded"
' IE.Document.All("Search for a template").Value = "text to search"
Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing
End Sub
HTML CODE:
<input title="Search for a template"
class="change-template__search-input ng-pristine ng-untouched ng-valid"
role="combobox"
aria-expanded="false"
aria-owns="typeahead-258-8737"
aria-autocomplete="list"
type="text"
placeholder="Search for a template"
ng-enter="getRecommendedTemplates(template.search)"
ng-model="template.search"
typeahead="template as template for template in getTemplateList($viewValue)"
typeahead-focus-first="false"
typeahead-on-select="getRecommendedTemplates($item)"
typeahead-min-length="3">

I think you need to search through all the elements returned by Document.All(). Try looping through the collection that is returned. This is much easier if the control had an id, but you will have to check each element having a title = "Search for a template". Once you have found the item you can set the text.
I suggest debugging so you can see what .All returns and then you can work from there.

welcome to SO. If you need to get an element, as drHodge said, using an iterator and some sort of ID attribute is usually enough. I tried this with Google a minute ago:
Dim Item As Object
For Each Item In IE.Document.all()
If Item.getAttribute("title") = "Buscar" Then
Item.Value = "Test"
End If
Next Item
I also made it press space, down arrow and enter, for the sake of doing something with the suggestion and searching part:
SendKeys ("{ }")
Application.Wait Now + TimeSerial(0, 0, 1)
SendKeys ("{DOWN}"), True
Application.Wait Now + TimeSerial(0, 0, 1)
SendKeys ("{ENTER}"), True
(I do not recommend using SendKeys on any script, tho; it's quite unreliable.)

You could try the following:
1) Focus and change
With ie.document.querySelector("[title='Search for a template']")
.focus
.value = "abcd"
End With
2) Javascript set value
ie.document.parentWindow.execScript "document.querySelector('[title=\'Search for a template\']').value = 'abcd';"
3) Attach event and fire
Dim evt As Object
Set evt = ie.document.createEvent("HTMLEvents")
evt.initEvent "change", True, False
With ie.document.querySelector("[title='Search for a template']")
.Focus
.Value = "abcd"
.dispatchEvent evt
End With
4) FireEvent
With ie.document.querySelector("[title='Search for a template']")
.Focus
.Value = "abcd"
.FireEvent "onchange"
End With

Related

How to use VBA to log into website on IE with data-automation-id tag?

I have read through so many websites, articles, and forums on this topic, but have not been able to get this to work for me. I am trying to log into a website using VBA in Excel, but I'm running into issues because the username and password text fields do not have a typical "name" or "id" associated with them. They instead have a "data-automation-id" which I can't figure out how to incorporate into the VBA code. My code errors out where the username and password are being entered into the website. I get the error "Object doesn't support this property or method." Any help would be greatly appreciated!
This is the HTML code for only the portions that refer to the username and password fields.
<input class="form-control__formControl___3uDUX" type="text" value="" data-automation-id="uname">
<input class="form-control__formControl___3uDUX" type="password" value="" data-automation-id="pwd">
<button disabled="" class="app-btn spin-wrapper spin-button spinner" data-automation-id="loginBtn">
This is the VBA code to access this site. NOTE: The username and password aren't real, and won't actually allow anyone to login even if the code works.
Sub test()
Dim IE As New InternetExplorer
Const cUsername = "blahblah#gmail.com"
Const cPassword = "somepassword"
IE.Visible = True
IE.navigate "https://retaillink.login.wal-mart.com/"
Do
DoEvents
Loop Until IE.readyState = READYSTATE_COMPLETE
Set HTMLDoc = IE.document
HTMLDoc.all.uname.Value = cUsername
HTMLDoc.all.pwd.Value = cPassword
For Each MyHTML_Element In HTMLDoc.getElementsByTagName(“input”)
If MyHTML_Element.Type = “submit” Then MyHTML_Element.Click: Exit For
Next
Err_Clear:
If Err <> 0 Then
Err.Clear
Resume Next
End If
End Sub
I test the code and found that when you try to set the value to the text boxes, it just shows the blank page while clicking the login button.
It can be possible that some code gets fired from the site when the user inputs the values manually. When we try to automate, it can possible that the code does not get triggered which leads us to a blank page.
I try to make a test by firing different events but it did not work.
As a workaround, you can try to use Sendkeys() instead of setting the value.
Sub demo()
Dim IE As New InternetExplorer
Dim allInputs As Object
Const cUsername = "blahblah#gmail.com"
Const cPassword = "somepassword"
IE.Visible = True
IE.navigate "https://Your_site_address_here.../" 'please modify the URL here...
While IE.Busy Or IE.readyState < 4: DoEvents: Wend
Application.Wait (Now + TimeValue("0:00:02"))
Set allInputs = IE.document.getElementsByTagName("input")
For Each inputx In allInputs
If inputx.getAttribute("data-automation-id") = "uname" Then
inputx.Focus
SendKeys (cUsername)
Application.Wait (Now + TimeValue("0:00:02"))
End If
If inputx.getAttribute("data-automation-id") = "pwd" Then
inputx.Focus
SendKeys (cPassword)
Application.Wait (Now + TimeValue("0:00:02"))
End If
Next inputx
IE.document.getElementsByTagName("button")(0).Click
End Sub
Output:
Since the page only contains two <input>, the guess is pretty easy.
First you get all the input of the page:
Set allInputs = IE.document.getElementsByTagName("input")
The list contains only two elements. Now, you can use the .getAttribute() function to check the value and set it accordingly:
For Each input In allInputs
If input.getAttribute("data-automation-id") = "uname" Then input.Value = cUsername
If input.getAttribute("data-automation-id") = "pwd" Then input.Value = cPassword
Next input
Then you get the only button present in the page and click it:
IE.document.getElementsByTagName("button")(0).Click

Filling Internet Explorer Forms from Excel

I want to fill information onto the site 'select picker' section on the left side of the picture.
SITE
There is an element name 'picker' but it won't work.
The search bar is being completed using jQuery auto-complete which submits a form that navigates to an associate from the auto-complete box has been selected
I tried
IE.Document.All("picker").Value = "Testing"
IE.Document.GetElementByID("pickerCtrl.currentPicker").Value = "Testing"
IE.Document.GetElementsByClassName("input-group input-group-sm").Item(0).Value = "Testing"
PS.
Is there way to just copy and paste the row at the current position where cursor is positioning at?
I can sendkeys tab 18 times to get to that specific search bar but do not know how to insert the entire row from my Excel sheet.
eg. IE.Document.all("picker").Value = ThisWorkbook.Sheets("Main_1").Range("B" & intRow).Value
I am completely new to this.
Try to make a test with example below may help to solve the issue.
Sub demo1()
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 = "D:\Backup20190913\tests\367.html"
IE.Navigate URL
Do While IE.ReadyState = 4: DoEvents: Loop
Do Until IE.ReadyState = 4: DoEvents: Loop
IE.Document.querySelector("[name='picker']").Value = "test value"
Stop
Set IE = Nothing
End Sub
HTML
<input class="form-control ng-valid ng-isolate-scope ng-touched ng-dirty" ng-model="pickerCtrl.currentpicker" name="picker" type="text" typeahead="" typeahead-source="pickerCtrl.getpickerStrings()" ng-disabled="pickerCtrl.errorLoadingPickers || pickerCtrl.noPickerstrings" ng-hide="pickerCtrl.disableTypeahead" autocomplete="off">
Output:

DOM VBA IE11 Automate Placing Orders on a Website - Trouble With OnChange and Picture Upload

We have a Virtual Assistant placing hundreds of orders for ball markers on this site:
https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm
I had used VBA before to get data from a website but I would like to use it to automate the placing of orders. I can get close but there are a few things tripping me up.
First of all, when you select a color with your mouse, the "Upload a Photo" box appears. I cannot get the box to show up using my VBA code.
Using VBA, I cannot make the onchange event fire for the life of me. I have tried the following four combinations:
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onclick")
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onclick")
Second, even if I can get the boxes to show and I click on "Upload a Photo", the popup box is there and I am having trouble putting the focus on it and I am unsure on how to tell the ID "fileField" what picture from my browse I want to upload. There is also a second Confirmation pop up.
If I can get the picture upload to work, I can successfully complete the automated order. Here is my code through clicking the Add to Cart button. The entirety of my "Upload Picture" section does not work and the last line under "Select the Color" does not make the "Upload a Photo" box show.
Dim IE As InternetExplorer
Dim doc As HTMLDocument
Set IE = New InternetExplorer
IE.Visible = True
'Go to the Ball Marker Page
ballMarkerURL = "https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm"
IE.navigate ballMarkerURL
'Wait for page to load
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
Set doc = IE.document
'Select the Color
doc.getElementById("2").Focus
doc.getElementById("2").selectedIndex = 2
doc.getElementById("2").FireEvent ("onchange")
'Upload Picture
markerFilePath = "M:\Cuddle Clones Share (Team Folder)\Operations\Vendors\Pet Prints\0 - Ready to Order - Golfballs.com\"
markerFileName = "380844 - Ball Marker - 200604-Red-1-of-1-qty-1.png"
fullString = markerFilePath & markerFileName
doc.getElementById("copyright_check").Checked
doc.getElementById("fileField").Value = fullString
doc.getElementById("upload").Click
doc.getElementById("saveBtn").Click
'Update Quantity
doc.getElementById("formQty").Value = 2
'Add to Cart
doc.getElementsByClassName("buttonStatic r addCart")(0).Click
In my original posting I explained how to trigger an event. Now I explain too how to click the "Upload a photo" button and focus the popup window.
The problem now is, the needed html document is in an iframe I can't access. I know there can be different reasons but none of them solve the problem.
This is, what I have now:
Sub SelectColorForGolfballs()
Dim objShell As Object
Dim objWindow As Object
Dim browser As Object
Dim url As String
Dim nodeColorDropDown As Object
Dim nodeThreeButtons As Object
Dim browserPopUp As Object
Dim nodeFrames As Object
Dim nodeIframeDoc As Object
Set objShell = CreateObject("Shell.Application")
url = "https://www.golfballs.com/Golf-Misc/Tools/Classic-Photo-Poker-Chips-3-Pack.htm"
'Initialize Internet Explorer, set visibility,
'call URL and wait until page is fully loaded
Set browser = CreateObject("internetexplorer.application")
browser.Visible = True
browser.navigate url
Do Until browser.ReadyState = 4: DoEvents: Loop
'Select color from dropdown
Set nodeColorDropDown = browser.document.getElementByID("2")
nodeColorDropDown.selectedIndex = 6 'Pink for testing
Call TriggerEvent(browser.document, nodeColorDropDown, "change")
'Manual break for loading the page complitly
'Application.Wait (Now + TimeSerial(pause_hours, pause_minutes, pause_seconds))
Application.Wait (Now + TimeSerial(0, 0, 2))
'Open Picture Upload
'The document changed, so you can't work with the old document here
'In a first step you need the div element with the three buttons
'we get in the last step by trigger dropdown event
'
'<div class="options-gallery">
' <a href="javascript:productSelection(1, 'P');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_P.jpg" title="Personalized" border="0">
' </a>
' <a href="javascript:productSelection(1, 'S');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_S.jpg" title="Photo" border="0">
' </a>
' <a href="javascript:productSelection(1, 'L');">
' <img src="https://d1tp32r8b76g0z.cloudfront.net/images/property/button/Half/Condition_L.jpg" title="Novelty" border="0">
' </a>
'</div>
Set nodeThreeButtons = browser.document.getElementsByClassName("options-gallery")(0)
'The second button must be clicked
nodeThreeButtons.FirstChild.NextSibling.Click
Application.Wait (Now + TimeSerial(0, 0, 2))
'Focus popup by runnig throuhg all open windows
For Each objWindow In objShell.Windows
'Check if it's an IE
If InStr(1, UCase(objWindow.FullName), "IEXPLORE") > 0 Then
'Check if it's the right IE
If InStr(1, objWindow.document.getElementsByTagName("title")(0).innertext, "iCusomize Image Selection") Then
Set browserPopUp = objWindow
Exit For
End If
End If
Next objWindow
'Now we can work with the popup
'It has only short code over all and a very short body
'You have to access the content of an iFrame
'
'Problem: I don't know why the following don't work
'I know it can't be in the same line
'You must split the access to the iFrame
'Get a node collection of all frames/ iframes of the document
Set nodeFrames = browserPopUp.document.frames
'The following line couses the error "Access denied"
'Select the first (and only) frame from the node collection
Set nodeIframeDoc = nodeFrames(0).document
'Check the copyright checkbox
nodeIframeDoc.getElementByID("copyright_check").Click
'If you are at this point we can look ahead
End Sub
And this procedure to trigger the event you need:
Private Sub TriggerEvent(htmlDocument As Object, htmlElementWithEvent As Object, eventType As String)
Dim theEvent As Object
htmlElementWithEvent.Focus
Set theEvent = htmlDocument.createEvent("HTMLEvents")
theEvent.initEvent eventType, True, False
htmlElementWithEvent.dispatchEvent theEvent
End Sub

Excel VBA: Check all check boxes on Web Page

I'm trying to check all the checkboxes available on a webpage via VBA since the name convention doesnt appear to be one in which I can be selective. However I cannot seem to get anything to work. I can login to the website and navigate to the section of the website I want but cannot cross this hurdle. Any help would be greatly appreciate. Below is the source code from the webpage.
<li data-product-family="30yr"
data-product-amortizationTerm="30"
data-product-type="Conventional"
data-product-amortizationType="Fixed"
>
<label>
<input type="checkbox"
value="154232"
class="product-Conventional product-item"
data-authorized-remittance-types="ActualActual "
/>30-Year Fixed Rate - 110k Max Loan Amount</label>
</li>
VBA I attempted to write (edited)... code I'm using presently:
Public Sub TestIE()
Dim IE As Object
Dim aNodeList As Object, i 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://"
' 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 aNodeList.Length
aNodeList.Item(i).Checked = True
Next i
End Sub
You can try to get a nodeList of the checkboxes with:
IE.document.querySelectorAll("input[type=checkbox]")
You can traverse the nodeList along its .Length property.
E.g.
Dim aNodeList As Object, i As Long
Set aNodeList = IE.document.querySelectorAll("input[type=checkbox]")
If aNodeList Is Nothing Then Exit Sub
For i = 0 To aNodeList.Length -1
On Error Resume Next
aNodeList.item(i).Checked = True
On Error GoTo 0
Next i

VBA Set Dropdown value

I have a macro that I have written in excel and I have navigated to a webpage using "ActiveWorkbook.FollowHyperlink", which works just as I need it!
However, I now need to update a dropdown menu on that webpage.
I have an ID for the dropdown and each selection obviously has a value. I want to set the selected option using the value, which I have in the excel sheet.
I am struggling because I don't know how to access elements on the page, once opened using .FollowHyperlink.
After .FollowHyperlink is the webpage then active, is there something like ActiveWebPage.getElementById?
Appreciate any help.
Mike
what you want to do is use com automation to call an instance of internet explorer and navigate to the page in question, this will give you the document model, from there you can do most anything, see IE (Internet Explorer) Automation using Excel VBA
Sample VBA follows
Private Sub IE_Autiomation()
Dim i As Long
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
' Create InternetExplorer Object
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False
IE.Navigate "http://www.excely.com/"
' Statusbar
Application.StatusBar = "www.excely.com is loading. Please wait..."
' Wait while IE loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
' Find 2 input tags:
' 1. Text field
' <input type="text" class="textfield" name="s" size="24" value="" />
'
' 2. Button
' <input type="submit" class="button" value="" />
Application.StatusBar = "Search form submission. Please wait..."
Set objCollection = IE.document.getElementsByTagName("input")
i = 0
While i < objCollection.Length
If objCollection(i).Name = "s" Then
' Set text for search
objCollection(i).Value = "excel vba"
Else
If objCollection(i).Type = "submit" And _
objCollection(i).Name = "" Then
' "Search" button is found
Set objElement = objCollection(i)
End If
End If
i = i + 1
Wend
objElement.Click ' click button to search
' Wait while IE re-loading...
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
' Show IE
IE.Visible = True
' Clean up
Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing
Application.StatusBar = ""
End Sub

Resources