I'm attempting to edit this textbox using VBA:
<td id="ctl00_PlaceHolderMain_ctl00_PlaceHolderMain_ProfileEditorValueAboutMe" class="ms-authoringcontrols" valign="top" style="padding-left:10px;padding-right:10px;"><span class="ms-profilevalue"><span id="ctl00_PlaceHolderMain_ProfileEditorEditAboutMe"><DIV id="ctl00_PlaceHolderMain_ProfileEditorEditAboutMe_editableRegion" class="ms-rtestate-write ms-inputuserfield ms-long" contentEditable="true" InputFieldId="ProfileEditorEditAboutMe_hiddenRTEField" style="height:125px;overflow:scroll;background-color:white;"><p>text box content here</p></DIV></span>
<div class="ms-profiledescription" style="width: 386px; white-space:normal;">Please enter some details in the textbox</div>
</span>
<table border="0">
<tr>
<td></td>
</tr>
</table>
</td>
Here is the VBA, which performs as expected, other than that the textbox doesn't change (either on screen or when the form is saved by the click event):
Dim ie As InternetExplorerMedium
Set ie = New InternetExplorerMedium
ie.Visible = True
ie.Navigate "URL"
While ie.Busy Or ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend
Debug.Print ie.Document.getelementbyid("ProfileEditorEditAboutMe_hiddenRTEField").Value
ie.Document.getelementbyid("ProfileEditorEditAboutMe_hiddenRTEField").Value = "<p>123</p>"
Debug.Print ie.Document.getelementbyid("ProfileEditorEditAboutMe_hiddenRTEField").Value
ie.Document.all("Button1").Click
The .value property does change, but the textbox does not.
I would be grateful for any ideas. As you can probably tell, I'm fairly new to VBA webscraping.
Since you're manipulating the value of the textbox yourself, you'll need to fire the onchange event in order for the textbox to repaint itself with your new value. This is done by creating an event object and then calling it via the dispatchEvent() function.
Dim e
Set e = ie.Document.getelementbyid("ProfileEditorEditAboutMe_hiddenRTEField")
' Set the value...
e.Value = "123"
' Fire the "onchange" event...
Dim objEvent
Set objEvent = ie.document.createEvent("HTMLEvents")
objEvent.initEvent "change", False, True
e.dispatchEvent objEvent
Related
I'm trying to trigger "on change" event upon selecting currency value from drop-down menu. This would update the mini spreadsheet on that page reflecting the value of the currency. However when changing the value through VBA jscript is not being triggered. I'm using IE to do this.
Set objIE = New InternetExplorer
objIE.Visible = True
objIE.navigate "https://www.reuters.com/markets/currencies"
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop
'Settlement Currency is Hard Coded to GBP
SettCcy = "GBP"
'Set Expression Currency
expCcy = "EUR"
'Set Target Currency
targetCcy = "USD"
On Error GoTo ResetIE
If expCcy <> SettCcy And expCcy <> targetCcy Then
'Set the rate refresher
Set clicker = objIE.document.getElementsByClassName("CurrencyCalculator-currency-swap-2yw2I")(0)
'Set the Expression Currency
For Each o In objIE.document.getElementsByTagName("select")(1) 'Sets Expression Currency
If o.Value = expCcy Then
o.Selected = True
o.FireEvent "onchange"
Exit For
End If
Next
All I need is that upon changing the value through VBA the page would update the same way as it would when doing it manually.
Please try to use the dispatchEvent method to dispatch the change event to the select element, then trigger the onchange event.
Sample code as below (you could refer to it and modify it, it works well on my side):
Public Sub ClickTest()
Dim ie As Object, evtChange As Object
Dim item As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate2 "<the website url>"
While .Busy Or .readyState <> 4: DoEvents: Wend
Set evtChange = .Document.createEvent("HTMLEvents")
evtChange.initEvent "change", True, False
'get the select element. Please note the index, it is starting from 0.
Set item = ie.Document.getElementsByTagName("select")(0)
expCcy = "EUR"
'Set the Expression Currency
For Each o In item 'Sets Expression Currency
If o.Value = expCcy Then
o.Selected = True
o.dispatchEvent evtChange
Exit For
End If
Next
End With
End Sub
The website resource like this:
<select id="ddlCurrency" onchange="ddlCurrencyChange()" >
<option value="GBP">GBP</option>
<option value="EUR">EUR</option>
<option value="USD">USD</option>
</select>
<script>
function ddlCurrencyChange() {
document.getElementById("result").innerHTML += "change event triggered... <br /> selected value is " + document.getElementById("ddlCurrency").value + "<br/>";
}
</script>
First time trying this.
I have the following HTML in a web page and I am using Excel and VBA to scrape data based on user addresses in my excel file. The issue I am having is the combobox does not accept any input but it has to be a selection from its drop down list.
I can select the input field and add my entry, but the drop list does not appear. The site is using an autocomplete where the list is built by an AJAX call once it detects an input.
How do I trigger the drop list in the combobox and select the correct entry from it to match the input from my range (if it exists)? The code below is one of my various attempts.
The url is http://play.afl/club-finder/? and I am trying to enter a suburb name in the last field next to the GO button. Try, for example, Parramatta
An observation is that for the combobox element:
<input role="combobox" aria-autocomplete="list" value="Parramatta, NSW" autocomplete="off">
If I type the value manually into the field, inspect shows the value= changing as I type it. When the vba changes this value, it does not get changed in inspect.
Thank you
<div class="program-filters">
<span>Search for </span>
<a>
any gender <img src="/site/images/svg/DownArrow.svg" alt="Down Arrow" class="down-arrow-icon">
</a>
<span class="xs-hide">,</span>
<br class="sm-hide md-hide lg-hide">
<a>
all ages <img src="/site/image/svg/DownArrow.svg" alt="Down Arrow" class="down-arrow-icon">
</a>
to
<a>
play <img src="/site/images/svg/DownArrow.svg" alt="Down Arrow" class="down-arrow-icon">
</a>
<br class="sm-hide md-hide lg-hide"> near
<div style="display: inline-block;">
<input role="combobox" aria-autocomplete="list" autocomplete="off" value="SEARCH VALUE HERE">
</div>
<a class="in-map-btn btn btn-primary btn-go btn-mobile-fixed">GO</a>
</div>
My macro so far is:
Sub get_data()
Const myURL As String = "http://play.afl/club-finder/?"
Dim c As Range
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Navigate myURL
.Visible = True
End With
Do While appIE.Busy
DoEvents
Loop
For Each c In Range("MY_SEARCH")
Set searchBar = appIE.document.getElementsByClassName("program-filters")(0)
Set myInput = searchBar.getElementsByTagName("INPUT")(0)
myInput.Focus
myInput.Value = c.Value
myInput.FireEvent ("onchange")
Set myAutoComplete = searchBar.getElementsByClassName("autocomplete")(0)
If Not myAutoComplete Is Nothing Then
'FIND IN LIST AND SELECT HERE
searchBar.getElementsByClassName("in-map-btn btn btn-primary btn-go btn-mobile-fixed")(0).Click
Do While appIE.Busy
DoEvents
Loop
'COLLECT DATA HERE
End If
Next
appIE.Quit
Set appIE = Nothing
End Sub
Tried executing jQuery from vba to trigger the AJAX, with no errors but not working:
appIE.Document.parentWindow.execScript "jQuery('.program-filters input').trigger('change')"
Using the suggestion below still not working though no errors:
jq = "jQuery('.program-filters input').val('" & c.Value & "').trigger('change')"
appIE.Document.parentWindow.execScript jq
You probably both have to fill in a value in the input field (combobox) AND trigger the change event for this to work. Try this:
appIE.Document.parentWindow.execScript "jQuery('.program-filters input').val('yourvalue').trigger('change')"
I am working on a personal project where I am getting some information from a website.
The website has a table. I know how to loop through each row and For each row I want to compare information with the contents of the first and fourth columns and, where both are matches to information from my table, copy the content of the fifth column in that row into my table but do not how to go about doing this.
This is what each row in the table html looks like.
<tr class="player_tr_1" data-url="/18/player/1/Pelé">
<td class="table-row-text" style="text-align: left;">
<img style="padding: 0;" class="player_img player_right_curve
form rating icon gold rare" src="./FIFA 18 Players _
FUTBIN_files/237067.png">
//Check info here
<a href="https://www.futbin.com/18/player/1/Edson%20Arantes"
class="player_name_players_table"> CHECK THIS TEXT </a>
</td> <td><span class="form rating icon gold rare">98</span> </td>
<td class="">CAM</td>
//Check info here
<td class="">CHECK THIS INFO</td>
//Grab info here
<td><span class="ps4_color"> GRAB THIS INFO </span></td>
<td><span class="xb1_color">0</span></td>
<td><span class="pc_color">0</span></td>
<td><span class="yellow_players_stat">76</span></td>
<td>173cm | 5'8"</td>
<td>77</td>
<td>516</td>
<td>2513</td>
</tr>
Here is the code I have so far:
It iterates through each row in the table and in that loop I need to grab info from that row. I commented in the loop for what I need to do specifically
Private Sub CommandButton1_Click()
SearchBot
End Sub
'start a new subroutine called SearchBot '
Sub SearchBot()
'dimension (declare or set aside memory for) our variables
Dim objIE As InternetExplorer 'special object variable representing the IE browser
Dim aEle As HTMLHtmlElement
Dim X As Integer 'integer variable we'll use as a counter
Dim version As String 'string variable that will hold our version '
Dim NumRows As Integer
'initiating a new instance of Internet Explorer and asigning it to objIE
Set objIE = New InternetExplorer
'make IE browser visible (False would allow IE to run in the background)
objIE.Visible = True
' Set numrows = number of rows of data.
NumRows = Range("A2", Range("A2").End(xlDown)).Rows.Count + 1
' Select cell a1.
Range("A2").Select
' Establish "For" loop to loop "numrows" number of times.
' screen is updated every time a new price is inserted '
Application.ScreenUpdating = True
For X = 2 To NumRows
' go to player page with correct name '
objIE.navigate "https://www.futbin.com/18/players?page=1&search=" & Sheets("Sheet1").Range("A" & X).Value
' wait '
Do While objIE.Busy = True Or objIE.readyState <> 4: DoEvents: Loop
' loop through each row '
For Each aEle In objIE.document.getElementsByTagName("tr")
' check player name, if correct loop through table to grab price if it is also the right version maybe or'
' or grab first elements text content, check if correct name, check 4th element for correct version, grab 5th element, and insert in table '
'if 1st element = Sheets("Sheet1").Range("A" & X).Value & "" '
' And 4th element = Sheets("Sheet1").Range("B" & X).Value Then '
'Sheets("Sheet1").Range("F" & X).Value = 5th element '
Next
Next
' click the correct version of the player '
'close the browser
objIE.Quit
MsgBox ("Done")
'exit our SearchBot subroutine '
End Sub
EDIT: As you can see in the html, the elements I'm trying to grab do not have class names.
Thanks in advance!
There seems to be only one element without any ID/class that you can use to identify it, so that you'll have to get by index while you get the rest by class name.
Dim FirstColumn As String
Set FirstColumn = aEle.getElementsByClassName("player_name_players_table")(1).innerText
Dim FourthColumn As String
Set FourthColumn = aEle.getElementsByTagName("td")(4).innerText
Dim FifthColumn As String
Set FifthColumn = aEle.getElementsByClassName("ps4_color")(1).innerText
Note that I'm not very used to VBA (I'm a VB.NET guy) so I'm not sure whether all the syntax is correct, nor if the returned arrays are starts at zero or one. :)
I need to login in a website.
Every time I make the credential insterted with VBA, after the click event, It say that the password is not correct.
If I make the credential inserted by VBA and if I manually cancel one letter of the username and I rewrite it and if I manually cancel one letter of the password and I rewrite it, after I send the click event with VBA it works.
which is the reason? Shound I insert the credential using kinda keypress event? Which is the correct syntax for that?
thanks
please see below HTML code and what I wrote in VBA
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.navigate "sss.html"
Do Until .ReadyState = 4
DoEvents
Loop
.Document.all.Item("login").Value = "username"
.Document.all.Item("password").Value = "password"
Set elems = ie.Document.getElementsByTagName("button")
For Each e In elems
If (e.innerHTML = "Confirm") Then
e.Click
Exit For
End If
Next e
<input type="text" ng-model="login" class="form-control ng-pristine ng-valid ng-touched" id="login" placeholder="Enter login (email)">
<input type="password" ng-model="password" class="form-control ng-pristine ng-valid ng-touched" id="password" placeholder="Password">
<button class="btn btn-default" ng-click="authenticate()" notranslate="">Confirm</button>
this website wants you to actually type your username/password and actually press the "Confirm" button, you can imitate it with SendKeys
so instead of setting the value and looping for the button element, use this code:
.Document.all.Item("login").focus
SendKeys "username", True
.Document.all.Item("password").focus
SendKeys "password", True
SendKeys "{TAB}", True
SendKeys "~", True
hope this helps.
I am writing a VBA code to open up a Internet Explorer, enter username and password and click a 'Sign On' Button.
Here is the code I have so far:
Sub Example()
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.navigate "webexample.com"
Do While IE.busy: DoEvents: Loop
Do While IE.READYSTATE <> 4: DoEvents: Loop
Do While IE.Document.READYSTATE <> "complete": DoEvents: Loop
IE.Document.all.Item("userID").Value = "username"
IE.Document.all.Item("password").Value = "password"
IE.Document.forms(0).submit ("Sign On")
End Sub
And here is the HTML for the "Sign On" button:
<input name="action" class="button" type="SUBMIT" value="Sign On">
Is there something I'm missing or need to correct? Any assistance is appreciated and I thank you in advance for your time and help!
Providing more HTML would help as there may be parent frame/iframe to handle.
The element you show can, without parent frame/iframe, be selected with CSS selector combinations of input.button[value='Sign On'].
That is input tag element with class button and attribute value with value 'Sign On'
ie.document.querySelector("input.button[value='Sign On']").Click