Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SendKeys doesn't always work

I am using .SendKeys() in Excel VBA to send key strokes to an external window that I am making active using shell .AppActive method. The problem is that SendKeys is simply not behaving consistently and is sometimes sending the keys and sometimes not. I think it has something to do with storing the keys in the buffer according to MSDN documentation.

How does one get around this?

like image 892
rex Avatar asked Jan 10 '14 08:01

rex


2 Answers

You may consider using Autoit which is more reliable than SendKeys.

Download Autoit from below link http://www.autoitscript.com/site/autoit/downloads/

Add in reference autoit addin AutoItX3 1.0 Type Library

Below is sample code which will open the calculator and type 123456789

Sub sendkeys()

'Open a calc
    StartCalculator

    Dim au As New AutoItX3Lib.AutoItX3
    au.AutoItSetOption "WinTitleMatchMode", 2

    au.WinActivate "Calculator"

    'send key strokes
    au.ControlClick "Calculator", "", "Button5"
    au.ControlClick "Calculator", "", "Button11"
    au.ControlClick "Calculator", "", "Button16"
    au.ControlClick "Calculator", "", "Button4"
    au.ControlClick "Calculator", "", "Button10"
    au.ControlClick "Calculator", "", "Button15"
    au.ControlClick "Calculator", "", "Button3"
    au.ControlClick "Calculator", "", "Button9"
    au.ControlClick "Calculator", "", "Button14"

End Sub

Sub StartCalculator()
    Dim Program As String
    Dim TaskID As Double
    On Error Resume Next
    Program = "calc.exe"
    TaskID = Shell(Program, 1)
    If Err <> 0 Then
        MsgBox "Can't start " & Program
    End If
End Sub

enter image description here

like image 92
Santosh Avatar answered Nov 10 '22 14:11

Santosh


I found that the solution to this problem was to just make the application pause for a short while. This seems to allow the buffer to clear (correct me if I'm wrong please).

In order to make Excel VBA sleep, I exposed the windows API function Sleep by writing at the top of a module:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

And then after every SendKeys command, I just used:

Sleep 1

And literally, 1 millisecond made all the difference and the keys were always sent correctly.

like image 33
rex Avatar answered Nov 10 '22 14:11

rex