Another option is to avoid SendKeys and use the Windows API as there are
some bugs with SendKeys.
Try this one:
Put all this code in a Class module:
Option Explicit
Private Declare Function MapVirtualKey _
Lib "user32" _
Alias "MapVirtualKeyA" _
(ByVal wCode As Long, _
ByVal wMapType As Long) As Long
Private Declare Function VkKeyScan _
Lib "user32" _
Alias "VkKeyScanA" _
(ByVal cChar As Byte) As Long
Private Declare Sub keybd_event _
Lib "user32" _
(ByVal bVk As Byte, _
ByVal bScan As Byte, _
ByVal dwFlags As Long, _
ByVal dwExtraInfo As Long)
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Private Declare Function GetKeyState _
Lib "user32" _
(ByVal nVirtKey As Long) As Long
Private Declare Function SetKeyboardState _
Lib "user32" _
(lppbKeyState As Any) As Long
Private Const KEYEVENTF_EXTENDEDKEY = &H1
Private Const KEYEVENTF_KEYUP = &H2
Public Enum eKeys
keyBackspace = &H8
keyTab = &H9
keyReturn = &HD
keyShift = &H10
keyControl = &H11
keyAlt = &H12
keyPause = &H13
keyEscape = &H1B
keySpace = &H20
keyEnd = &H23
keyHome = &H24
keyLeft = &H25
KeyUp = &H26
keyRight = &H27
KeyDown = &H28
keyInsert = &H2D
keyDelete = &H2E
keyF1 = &H70
keyF2 = &H71
keyF3 = &H72
keyF4 = &H73
keyF5 = &H74
keyF6 = &H75
keyF7 = &H76
keyF8 = &H77
keyF9 = &H78
keyF10 = &H79
keyF11 = &H7A
keyF12 = &H7B
keyNumLock = &H90
keyScrollLock = &H91
keyCapsLock = &H14
End Enum
Public Enum eLockKey
CapsLock = keyCapsLock
NumLock = keyNumLock
ScrollLock = keyScrollLock
End Enum
Private zlKeyPressDelay As Long
'Purpose : Press a single key represented by a string
'Inputs : sKey The key to press.
' [bHoldKeydown] If True does not
'release the key press.
' [bRelease] If True releases a
'"HoldKeydown" key press (see above).
'Outputs : N/A
Public Sub SendKey(sKey As String, _
Optional bHoldKeydown As Boolean = False, _
Optional bRelease As Boolean = False)
Dim lScan As Long
Dim lExtended As Long
Dim lVK As Long
Dim bShift As Boolean
Dim bCtrl As Boolean
Dim bAlt As Boolean
lVK = VkKeyScan(Asc(sKey))
If lVK Then
lScan = MapVirtualKey(lVK, 2)
lExtended = 0
If lScan = 0 Then
lExtended = KEYEVENTF_EXTENDEDKEY
End If
lScan = MapVirtualKey(lVK, 0)
bShift = (lVK And &H100)
bCtrl = (lVK And &H200)
bAlt = (lVK And &H400)
lVK = (lVK And &HFF)
If bRelease = False Then
If bShift Then
keybd_event eKeys.keyShift, 0, 0, 0
End If
If bCtrl Then
keybd_event eKeys.keyControl, 0, 0, 0
End If
If bAlt Then
keybd_event eKeys.keyAlt, 0, 0, 0
End If
keybd_event lVK, lScan, lExtended, 0
End If
If bHoldKeydown = False Then
keybd_event lVK, lScan, KEYEVENTF_KEYUP Or lExtended, 0
If bShift Then
keybd_event eKeys.keyShift, 0, KEYEVENTF_KEYUP, 0
End If
If bCtrl Then
keybd_event eKeys.keyControl, 0, KEYEVENTF_KEYUP, 0
End If
If bAlt Then
keybd_event eKeys.keyAlt, 0, KEYEVENTF_KEYUP, 0
End If
End If
End If
End Sub
'Purpose : Loops through a string and calls SendKey for each character
'Inputs : sString The string to press.
' [bDoEvents] If True returns control to the
processor
'after every keypress.
'Outputs : N/A
Public Sub SendString(ByVal sString As String, _
Optional bDoEvents As Boolean = True)
Dim sKey As String * 1
Dim lKey As Long
Dim lLen As Long
lLen = Len(sString)
For lKey = 1 To lLen
sKey = Mid$(sString, lKey, 1)
SendKey sKey
Sleep zlKeyPressDelay
'----------------------------
'doesn't work with DoEvents '
'----------------------------
If bDoEvents Then
DoEvents
End If
Next
End Sub
'Purpose : Presses a virtual key (used for keys that don't have ascii
equilivant)
'Inputs : ekeyPress The virtual key to press
' [bHoldKeydown] If True does not release the key
press.
' [bRelease] If True releases the key press.
' [bCompatible]
'Outputs : N/A
Public Sub PressKeyVK(ekeyPress As eKeys, _
Optional bHoldKeydown As Boolean, _
Optional bRelease As Boolean, _
Optional bCompatible As Boolean)
Dim lScan As Long
Dim lExtended As Long
lScan = MapVirtualKey(ekeyPress, 2)
lExtended = 0
If lScan = 0 Then
lExtended = KEYEVENTF_EXTENDEDKEY
End If
lScan = MapVirtualKey(ekeyPress, 0)
If bCompatible Then
lExtended = 0
End If
If Not bRelease Then
keybd_event ekeyPress, lScan, lExtended, 0
End If
If Not bHoldKeydown Then
keybd_event ekeyPress, lScan, KEYEVENTF_KEYUP Or lExtended, 0
End If
End Sub
'Purpose : Sets the status of the various Lock keys
'Inputs : LockKey The lock key to set the status of.
'Outputs : N/A
Public Sub SetLockStatus(LockKey As eLockKey, bOn As Boolean)
Dim abKeys(0 To 256) As Byte
abKeys(LockKey) = (bOn * -1)
'Win 9x
Call SetKeyboardState(abKeys(0))
'GetKeyState returns 1 if OFF and 0 if ON
If GetKeyState(LockKey) <> IIf(bOn, 0, 1) Then
'Win NT
'Simulate Key Press
keybd_event LockKey, &H45, KEYEVENTF_EXTENDEDKEY Or 0, 0
'Simulate Key Release
keybd_event LockKey, &H45, KEYEVENTF_EXTENDEDKEY Or _
KEYEVENTF_KEYUP, 0
End If
End Sub
'Purpose : returns the status of the various Lock keys
'Inputs : LockKey The lock key to return the status of.
'Outputs : Returns True if the Lock status is on.
Public Function GetLockStatus(LockKey As eLockKey) As Boolean
GetLockStatus = GetKeyState(LockKey)
End Function
'Determines the delay between subsequent keystrokes in the SendString
routine
Property Get KeyPressDelay() As Long
KeyPressDelay = zlKeyPressDelay
End Property
Property Let KeyPressDelay(Value As Long)
zlKeyPressDelay = Value
End Property
Private Sub Class_Initialize()
zlKeyPressDelay = 20 'Add a delay of 20 ms between pressing each key
End Sub
Then in a normal module put this code:
Sub test()
Dim cSK As clsSendKeys
Set cSK = New clsSendKeys
cSK.SendString "select", False
cSK.PressKeyVK keyReturn
End Sub
See if that works.
RBS