Excel VBA application.sendkeys "^C", True 无效

Excel VBA application.sendkeys "^C", True not working

我正在使用 Excel VBA 从 Access 文件复制文本选择(我不想详细说明原因)。我在一个 Do While 循环中应该按 tab 键(有效),然后复制数据(失败),将其放入剪贴板(有效),并将剪贴板信息设置为变量(有效),然后,出于调试目的,对变量执行 debug.print (有效)。这是循环浏览一个表单以到达 "base point",我可以 100% 使用选项卡等导航到表单的其他部分。请看代码:

AppActivate ("Microsoft Access - Filename that is constant")

X = 0
Do While X < 14
Application.SendKeys "{TAB}", True
Application.SendKeys "^C", True

Sleep (500)

mydata.GetFromClipboard
cb = mydata.GetText

Debug.Print (cb)
If Len(cb) = 5 Then
X = 14
End If
X = X + 1
Loop
Set mydata = Nothing

我试过让它工作,但无济于事。我做错了什么或者更好的解决方案是什么?

虽然我讨厌Sendkeys并且在想我是否应该问你这件事但是既然你说不要问为什么,我就闭嘴了。 :P

尝试这个小修复...如果可行,那么这意味着您需要在发出下一个 sendkeys 命令之前给它一些时间。

Sub Sample()
    '
    '~~> Rest of your code
    '

    Application.SendKeys "{TAB}", True

    Wait 2

    Application.SendKeys "^{C}", True

    '
    '~~> Rest of your code
    '
End Sub

Private Sub Wait(ByVal nSec As Long)
    nSec = nSec + Timer
    While nSec > Timer
        DoEvents
    Wend
End Sub

what would be a better solution?

使用 APIs,如图 Here。这并没有直接回答你的问题,但它解释了这个概念是如何工作的。

所以应用它就像这样

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Dim Ret As Long

Sub Sample()
    Ret = FindWindow(vbNullString, "Microsoft Access - Filename that is constant")

    If Ret <> 0 Then
        MsgBox "Window Found"
    Else
        MsgBox "Window Not Found"
    End If
End Sub

如果您希望擅长 API,例如 FindWindowFindWindowExSendMessage,那么请获取一个工具,它可以让您以图形方式查看系统的进程、线程、windows 和 window 消息。例如:uuSpySpy++。另一个 example 演示如何使用此 API。

我明白了。我从这里复制代码:http://www.vbaexpress.com/forum/showthread.php?38826-SendInput()-in-Excel-64Bit 我将 VkkeyMenu 更改为 VbKeyControl,并将 "f" 键更改为 "C"。我知道它可以简化为占用更少的行,但如果它像谚语 "If it ain't broke, don't fix it." 代码:

那样工作,我宁愿不要乱用它
Private Declare PtrSafe Function SendInput Lib "user32" (ByVal nInputs As LongPtr, pInputs As Any, ByVal cbSize As LongPtr) As LongPtr
Private Declare PtrSafe Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (ByVal cChar As Byte) As Integer
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Type KeyboardInput '   creating variable type
dwType As Long '   input type (keyboard or mouse)
wVk As Integer '   the key to press/release as ASCSI scan code
wScan As Integer '   not required
dwFlags As Long '   specify if key is pressed or released
dwTime As Long '   not required
dwExtraInfo As Long '   not required
dwPadding As Currency '   only required for mouse inputs
End Type



' SendInput constants
Private Const INPUT_KEYBOARD As Long = 1


Private Const KEYEVENTF_EXTENDEDKEY As Long = 1
Private Const KEYEVENTF_KEYUP As Long = 2


' Member variables


Private TheKeys() As KeyboardInput
Private NEvents As Long




Sub testage()


ReDim TheKeys(0 To 3)


With TheKeys(0)

    .dwType = INPUT_KEYBOARD 'operation type
    .wVk = vbKeyControl 'press CTRL key

End With


With TheKeys(1)


    .dwType = INPUT_KEYBOARD ' operation
    .wVk = VkKeyScan(Asc("C")) 'press chr key

End With


With TheKeys(2)

    .dwType = INPUT_KEYBOARD 'operation type
    .wVk = VkKeyScan(Asc("C"))
    .dwFlags = KEYEVENTF_KEYUP 'release chr key

End With


With TheKeys(3)


    .dwType = INPUT_KEYBOARD ' operation type
    .wVk = vbKeyControl
    .dwFlags = KEYEVENTF_KEYUP 'release CTRL Key


End With
Call SendInput(4, TheKeys(0), Len(TheKeys(0)))


Erase TheKeys


End Sub