2

我正在使用 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

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

4

2 回答 2

0

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

什么是更好的解决方案?

使用此处所示的 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 FindWindowFindWindowEx然后SendMessage获得一个工具,它可以为您提供系统进程、线程、窗口和窗口消息的图形视图。例如:uuSpySpy++。另一个演示如何使用此 API 的示例。

于 2015-05-12T21:51:49.360 回答
0

我想到了。我从这里复制了代码: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
于 2015-05-13T21:38:21.207 回答