在VBA shell命令中使用AppActivate和Sendkeys

时间:2011-01-12 23:35:16

标签: shell vba sendkeys

我想在VBA中使用shell命令在应用程序之间来回切换。 我正在使用SendKeys来处理进程A中的内容然后转移到进程B,然后进行处理A然后进程B.它适用于第一次迭代。当我使用AppActivate回到进程B时,它确实将焦点切换回进程B.但是,它忽略了来自SendKeys的后续命令。

示例代码:

Sub pastePDF2TXT_v3(pdfName As String, txtName As String)


Dim acrobatID
Dim acrobatInvokeCmd As String
Dim acrobatLocation As String

Dim notepadID

Dim acrobatID2
Dim notepadID2

Debug.Print "here"


acrobatLocation = "C:\Program Files\Adobe\Acrobat 9.0\Acrobat\Acrobat.exe"

acrobatInvokeCmd = acrobatLocation & " " & pdfName

acrobatID = Shell(acrobatInvokeCmd, 1)
AppActivate acrobatID
SendKeys "^a", True  '^A selects everything already in the pdf file.
SendKeys "^c", True  '^C copies the selection to the clipboard.



notepadID = Shell("NOTEPAD.EXE " & txtName, 1)  ' invoke notepad on the text file.
AppActivate notepadID                           ' set the new app as teh active task.

SendKeys "^a", True  '^A selects everything already in the text file.
SendKeys "^v", True  '^V pastes the new stuff over the top of the old text file (deleting the old stuff)
SendKeys "%{END}", True ' makre sure last line of text file 
SendKeys "{ENTER}", True



AppActivate acrobatID  ' NOTE: APPEARS TO WORK UP TO THIS POINT.

SendKeys "{ENTER}", True  ' NOTE: SECOND APP IGNORES SUBSEQUENT COMMANDS FROM HERE DOWN.
SendKeys "^a", True  '^A selects everything already in the pdf file.
SendKeys "^c", True  '^C copies the selection to the clipboard.
SendKeys "%f", True  'alt f, x to exit Notepad.exe
SendKeys "x", True
'acrobatID.Quit


Debug.Print "start second"

AppActivate notepadID                           ' set the new app as teh active task.


SendKeys "%{END}", True 'Go to end of text file.
SendKeys "^v", True  '^V pastes the new stuff at end of file.
SendKeys "{ENTER}", True

SendKeys "^s", True   

SendKeys "%f", True   'alt f, x to exit Notepad.exe
SendKeys "x", True

notepadID.Quit
acrobatID.Quit

End Sub

6 个答案:

答案 0 :(得分:3)

我知道这个问题已经过时了,但是我遇到了同样的问题,但我不认为所选的答案是正确的。

当您调用AppActivate时,脚本将暂停,等待目标应用程序终止。应用程序终止后,脚本继续。我认为没有解决这个问题的方法。

编辑:

我使用批处理文件为AppActivate命令调用CSCRIPT,我注意到你正在严格使用VBS文件。尝试将CMD作为新窗口调用并传递CSCRIPT //NoLogo //B WScript.CreateObject("WSCript.shell").AppActivate("Window Name")作为参数,看看是否绕过了问题。

答案 1 :(得分:2)

这可能更多是评论而不是答案,但我似乎不允许“评论”,所以......

令人惊讶的是,你已经做到了这一点。机会是,你永远无法使这项工作可靠 - 期间。一旦你确实工作,有关Acrobat UI在未来版本中的行为方式会有所改变,或者Windows会对事件的其他事情发送事件的规则进行另一次更改,然后你再次被冲洗

在这种情况下,您可能遇到的是Windows试图阻止应用程序在用户显然忙于与第一个交互时窃取焦点。您会看到同样的问题,例如在一个应用程序中使用按钮将数据写入临时文件并打开MS Word进行编辑。 Windows会阻止焦点从当前应用程序转移到MS Word,因为您只需单击当前应用程序中的按钮。

所以 - 不要试图解决这个不可能的技术问题,让我们退后一步,问一下你原本希望通过做所有这些来完成的事情。也许,通过这种方式,我们可以帮助您实现目标:)

答案 2 :(得分:2)

同样地,我试图在我用shell命令打开的pdf文档上使用AppActivate,以便我可以在其上使用SendKeys。它总是会生成运行时错误'5'。我的解决方案,最终是根本不使用AppActivate,实际上打开文档无论如何都将它带到了最前沿。问题是SendKeys语句在shell命令之后立即执行,但pdf需要一两秒才能打开。我的解决方案是在排除sendkeys语句之前暂停代码几秒钟。

我使用了时间延迟的pootle flump。看看这里的主题: http://www.dbforums.com/microsoft-access/1219379-time-delay-vba.html

答案 3 :(得分:2)

在各种论坛上进行了数小时的研究后,我发现我无法使用Adobe Reader中的Adobe库对象和函数。剩下的唯一可行选择是使用Shell命令来使用Adobe Reader文件菜单中提供的“另存为文本”选项。快捷键是 Alt + f + a + x + s 。我在下面的代码中实现了这些功能,虽然我需要在某些步骤中插入延迟。

Sub SavePDFasText()
Dim AdobeReaderPath As String
Dim PdfFilePath As String
Dim PDFid, NotepdId As Double

AdobeReaderPath = "C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe"
PdfFilePath = "D:\PowerGenMacro\opm_11.pdf"
PDFid = Shell(AdobeReaderPath & " " & PdfFilePath, vbNormalFocus)
Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 5)
'Alt+f+a+x is required to save the pdf as text in the adobe reader
SendKeys "%(FAX)", True
Application.Wait TimeSerial(Hour(Now()), Minute(Now()), Second(Now()) + 2)
SendKeys "%S", True
SendKeys "^q", True

End Sub

答案 4 :(得分:0)

尝试  sendkeys“%{tab}” 切换窗口 但是后面只保留2个活动窗口。

或尝试 仅在sendkeys {Tab}之后激活,以便在switchibg windows cmd之前未选择文本输入框。

或尝试 尝试appactivate窗口名称,1 然后睡2000°,以便有时间让窗户聚焦

答案 5 :(得分:0)

您忘记在每个sendkey和某种延迟/等待时间之间添加“ DoEvents”,给它一些执行时间。