I woud like to buy on gdax automatically. But my inputs in the Amount window doesn´t get recognized. I can see that on the little field, that says: Total (LTC) ≈ 0.00000000
My code:
Sub test()
Dim ObjIE As New InternetExplorer
Dim Ohtml As HTMLDocument
Dim HTMLtags As IHTMLElementCollection
Dim HTMLtag As IHTMLElement
Dim HTMLobjekt As IHTMLElement
Dim item_limit As Object
Dim y As Integer
With ObjIE
.Visible = True
.navigate "https://www.gdax.com/trade/LTC-EUR"
Do Until .readyState = READYSTATE_COMPLETE: Loop
Set Ohtml = .document
End With
'Amount
Do
Set HTMLtags = Ohtml.getElementsByClassName("OrderForm_input-box_XkGmi")
DoEvents
Loop While HTMLtags.Length = 0
For Each HTMLtag In HTMLtags
If HTMLtag.Children(1).innerText = "EUR" Then
Set HTMLobjekt = HTMLtag.Children(0)
HTMLobjekt.Value = 100 ' this is the part that i excanged
End If
Next HTMLtag
'get the Total(LTC) to cross check
Do
Set HTMLtags = Ohtml.getElementsByClassName("OrderForm_total_6EL8d")
DoEvents
Loop While HTMLtags.Length = 0
For Each HTMLtag In HTMLtags
Debug.Print HTMLtag.innerText & "Total(LTC)"
Next HTMLtag
End Sub
This is what the website says when the code is done:
![](https://www.manongdao.com/static/images/pcload.jpg)
and this is how it should look like, and looks when I type the number in manually:
![](https://www.manongdao.com/static/images/pcload.jpg)
I also exchange the marked part with things like:
HTMLobjekt.innerText = 100
or
HTMLobjekt.innerText = "100"
or
HTMLobjekt.Value = "100"
but nothing worked.
You need to make sure the page is fully loaded before you take any initiative. I checked for the availability of one such class generated dynamically OrderBookPanel_text_33dbp
. Then I did the rest what you tried to do. Lastly, you need to Focus
the target before putting that amount in the placeholder. Applying all of the above, your script should more like below:
Sub Get_Value()
Dim HTML As HTMLDocument, tags As Object
Dim tag As Object, ival As Object
With CreateObject("InternetExplorer.Application")
.Visible = True
.navigate "https://www.gdax.com/trade/LTC-EUR"
While .Busy = True Or .readyState < 4: DoEvents: Wend
Set HTML = .document
Do: Set tags = HTML.querySelector("[class^='OrderBookPanel_text_']"): DoEvents: Loop While tags Is Nothing
Do: Set tag = HTML.querySelector("input[name='amount']"): DoEvents: Loop While tag Is Nothing
tag.Focus
tag.innerText = 100
Set ival = HTML.querySelector("[class^='OrderForm_total_']")
[A1] = ival.innerText
.Quit
End With
End Sub
Output at this moment:
0.79139546
Not a complete answer, just a direction. Open the webpage https://www.gdax.com/trade/LTC-EUR in a browser (e. g. Chrome). Click to open context menu on the target element (step 1 on the below screenshot), click Inspect (2), from opened developer tools on the right you can see target element (3), and that there is a bunch of event listeners attached to target object (4). One of the handlers is input
on the document
node level. Actually the amount is updated by this event handler, when event is bubbled from <input>
node. You can easily check that by deleting all other event handlers (click on their Remove buttons). But if you delete particularly this input
handler (5) then there will be no update (until you reload the webpage).
![](https://www.manongdao.com/static/images/pcload.jpg)
So, to mimic user activity you need to create such input
event object and dispatch it to the target <input>
node. Note <input>
node and input
control event is completely different things just having the same name.
Tracing event handler execution in IE can be done in debugger. Open IE developer tools (press F12), go to Debugger tab (step 1 on the below screenshot), Breakpoints tab (2), click Add event breakpoint (3), choose input event (4). Now any input event will pause code execution and open debugger window (5).
![](https://www.manongdao.com/static/images/pcload.jpg)
If you try to type in the amount textbox on the webpage, debugger will show event handler function code:
![](https://www.manongdao.com/static/images/pcload.jpg)
You may resume execution (F5), or make step into / over / out. To see event object passed to the function, type arguments
in console, there is output for standard event handler call after typing manually:
![](https://www.manongdao.com/static/images/pcload.jpg)
I tested the below test code to trigger that event from VBA:
Sub Test()
Dim oEvt As Object
With CreateObject("InternetExplorer.Application")
.Visible = True
.Navigate "https://www.gdax.com/trade/LTC-EUR"
Do While .ReadyState < 4 Or .Busy
DoEvents
Loop
With .Document
Do While IsNull(.querySelector("div.OrderForm_input-box_XkGmi input"))
DoEvents
Loop
Set oEvt = .createEvent("Event")
oEvt.initEvent "input", True, False, .parentWindow, 1
With .querySelector("div.OrderForm_input-box_XkGmi input")
.Focus
.Value = "1000"
.dispatchEvent oEvt
Stop
End With
End With
End With
End Sub
As a result, absolutely the same actions take place as in case of typing the amount manually. It works without any errors. But Total (LTC) isn't updated. Debugger pauses execution as well, and the output for event object is as follows:
![](https://www.manongdao.com/static/images/pcload.jpg)
The only difference is that isTrusted
property is True
for standard call,
and False
for call via VBA. I guess that is why updating is skipped somewhere in the handler code. I tried to trace the entire code execution till event handler completion, but seems that is huge reverse engineering work, which I can't devote time for at the moment.
Currently I'm stucked in my investigations at that point.
Sorry could not get to work but have nudged along the problem.
I managed to figure out the correct syntax for creating and raising an event in higher versions of Internet Explorer (thanks to this SO answer ) . I managed to raise an input event for the input box, that followed on from omegastripes excellent lead.
So it works for a local file which I give below that has the same essential structure of the real page.
But when I run the code on the real page it simply does not work and I do not know why.
Where possible I'm feeding javascript into IE for it to execute to miminise issues with the VBA/COM/MSHTML interoperability bridge. I do this by calling window.execScript
passing the javascript as a string.
I hope someone can pick up this ball and run it over the goal line. For me, I have reached the end.
Here is the local html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<input id="Button1" type="button" value="Programmatically write textbox value" onclick="TestAlert()" />
<form class="OrderForm_form_25r0u">
<ul class="OrderForm_trade-type_2QyK4">
<li class="OrderForm_trade-type-tab_uWGMp OrderForm_active_Di-9p">MARKET</li>
<li class="OrderForm_trade-type-tab_uWGMp">LIMIT</li>
<li class="OrderForm_trade-type-tab_uWGMp">STOP</li>
</ul>
<ul class="OrderForm_toggle_120Ka">
<li class="OrderForm_toggle-tab_bZZnC OrderForm_buy_38n5g OrderForm_active_Di-9p">BUY</li>
<li class="OrderForm_toggle-tab_bZZnC OrderForm_sell_3vYRQ">SELL</li>
</ul>
<div class="market-order">
<div class="OrderForm_section_2Znad">
<div class="OrderForm_section-header_fwFDB">Amount</div>
<div class="OrderForm_input-box_XkGmi">
<input type="number" step="0.01" min="0" name="amount" placeholder="0.00" value="" autocomplete="off" oninput="myOnInputHandler()">
<span>EUR</span>
</div>
</div>
</div>
<div class="OrderForm_order-total_3Mkdz">
<div>
<b>Total</b>
<span>(LTC)</span>
<b>≈</b>
</div>
<div class="OrderForm_total_6EL8d" >0.00000000</div>
</div>
</form>
<script language="javascript">
function myOnInputHandler() {
print_call_stack();
alert('you input something');
}
function print_call_stack() { console.trace(); }
function print_call_stack2() {
var stack = new Error().stack;
console.log("PRINTING CALL STACK");
console.log(stack);
}
function TestAlert() { setInputBox(document); }
function setInputBox() {
try {
var inputBox = document.querySelector('div.OrderForm_input-box_XkGmi input'); inputBox.value = 100; if (document.createEvent) { var event2 = document.createEvent("HTMLEvents"); event2.initEvent("input", true, true); event2.eventName = "input"; inputBox.dispatchEvent(event2); }
return ({ success: true });
}
catch (ex) {
return ({ exception: ex, myMsg: '#error in setInputBox!' });
}
}
</script>
</body>
</html>
Here is the VBA
Option Explicit
'* Tools - References
'* MSHTML Microsoft HTML Object Library C:\Windows\SysWOW64\mshtml.tlb
'* SHDocVw Microsoft Internet Controls C:\Windows\SysWOW64\ieframe.dll
'* Shell32 Microsoft Shell Controls And Automation C:\Windows\SysWOW64\shell32.dll
Private Function ReacquireInternetExplorer(ByVal sMatch As String) As Object
Dim oShell As Shell32.Shell: Set oShell = New Shell32.Shell
Dim wins As Object: Set wins = oShell.Windows
Dim winLoop As Variant
For Each winLoop In oShell.Windows
If "C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" = winLoop.FullName Then
Dim sFile2 As String
sFile2 = "file:///" & VBA.Replace(sMatch, "\", "/")
If StrComp(sFile2, winLoop.LocationURL, vbTextCompare) = 0 Then
Set ReacquireInternetExplorer = winLoop.Application
GoTo SingleExit
End If
End If
Next
SingleExit:
End Function
Sub test()
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
Dim oHtml As HTMLDocument
Dim HTMLtags As IHTMLElementCollection
Dim sUrl As String
sUrl = "C:\Users\Simon\source\repos\WebApplication2\WebApplication2\HtmlPage1.html"
'sUrl = "http://localhost:50367/HtmlPage1.html"
sUrl = "https://www.gdax.com/trade/LTC-EUR"
objIE.Visible = True
objIE.Navigate sUrl
If StrComp(Left(sUrl, 3), "C:\") = 0 Then
Stop '* give chance to clear the activex warning box for the local file
Set objIE = ReacquireInternetExplorer(sUrl)
End If
Do Until objIE.readyState = READYSTATE_COMPLETE: DoEvents: Loop
Set oHtml = objIE.Document
Do
'* wait for the input box to be ready
Set HTMLtags = oHtml.getElementsByClassName("OrderForm_input-box_XkGmi")
DoEvents
Loop While HTMLtags.Length = 0
Dim objWindow As MSHTML.HTMLWindow2
Set objWindow = objIE.Document.parentWindow
'* next line would be really useful if it worked because it prints the stack trace in the console window
'* and we would be able to see the needle in the haystack where te order total gets updated
'* works on local file but not on https://www.gdax.com/trade/LTC-EUR **sigh**
objWindow.execScript "var divTotal = document.querySelector('div.OrderForm_total_6EL8d'); divTotal.onchange = function() { console.trace(); }"
'* next line sets the input box and raises an event, works on local file but not on GDAX
objWindow.execScript "var inputBox = document.querySelector('div.OrderForm_input-box_XkGmi input'); inputBox.value = 100; if (document.createEvent) { var event2 = document.createEvent('HTMLEvents'); event2.initEvent('input', false, false); event2.eventName = 'input'; inputBox.dispatchEvent(event2); }"
'get the Total(LTC) to cross check
Do
'* wait for the order total div to be ready
Set HTMLtags = oHtml.getElementsByClassName("OrderForm_total_6EL8d")
DoEvents
Loop While HTMLtags.Length = 0
Dim divTotal As HTMLDivElement
Set divTotal = oHtml.querySelector("div.OrderForm_total_6EL8d")
Debug.Print divTotal.innerText & " Total(LTC)"
Stop
End Sub