【问题标题】:Excel VBA application.sendkeys "^C", True not workingExcel VBA application.sendkeys "^C", True 不工作
【发布时间】:2015-07-23 23:39:26
【问题描述】:

我正在使用 Excel VBA 从 Access 文件中复制文本选择(我不想详细说明原因)。我在 Do While 循环中应该按 Tab 键(有效),然后复制数据(失败),将其放入剪贴板(有效),并将剪贴板信息设置为变量(有效),然后,出于调试目的,对变量进行 debug.print(工作)。这是循环浏览表单以到达“基点”,在该“基点”中,我可以 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

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

【问题讨论】:

    标签: excel ms-access copy-paste data-objects vba


    【解决方案1】:

    虽然我讨厌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
    

    什么是更好的解决方案?

    使用Here 所示的 API。这并不能直接回答您的问题,但它解释了这个概念的工作原理。

    所以应用它会是这样的

    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,那么请获取一个工具,该工具可为您提供系统进程、线程、窗口和窗口消息的图形视图。例如:uuSpySpy++。另一个 example 演示了如何使用此 API。

    【讨论】:

    • 1.不工作。我用睡眠(毫秒)试过它,它不起作用。手动执行 CTRL+C 即可。
    • 2.我的意思是“不要问”复制/粘贴 Access 表单数据。如果您对 SendKeys 有更好的解决方案,我很想听听!
    • 顺便说一句,你试过SendKeys "^{C}"而不是.SendKeys "^C"
    • 已经发布了 :) 您可能需要刷新页面才能看到它 :)
    • Sendkeys 不同,使用 API 是一件更复杂但更可靠的事情。我建议阅读它:)
    【解决方案2】:

    我想通了。我从这里复制了代码:http://www.vbaexpress.com/forum/showthread.php?38826-SendInput()-in-Excel-64Bit 我将 VkkeyMenu 更改为 VbKeyControl,将“f”键更改为“C”。我知道它可以简化为占用更少的行,但如果它像“如果它没有坏,就不要修复它”这样的说法,我宁愿不要乱用它。代码:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-04
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多