6

我想在 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
4

6 回答 6

4

我知道这个问题很老,但我遇到了同样的问题,但我不认为选择的答案是正确的。

当您调用 AppActivate 时,脚本会停止,等待目标应用程序终止。应用程序终止后,脚本将继续。我看不到这个问题的解决方案。

编辑:

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

于 2012-01-24T22:38:06.683 回答
2

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

我使用了 pootle flump 的延时屈膝礼。在这里查看线程: http ://www.dbforums.com/microsoft-access/1219379-time-delay-vba.html

于 2012-08-17T15:03:20.543 回答
2

在各种论坛上进行了数小时的研究后,我发现我无法将 Adob​​e 库对象和函数与 Adob​​e Reader 一起使用。剩下的唯一可行选项是使用 Shell 命令来使用 Adob​​e 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
于 2014-01-13T18:33:30.397 回答
0

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

你能走到这一步真是太神奇了。很有可能,你永远无法可靠地完成这项工作——期间。一旦你让它工作,Acrobat UI 在未来版本中的行为方式就会发生变化,或者 Windows 将对哪些事物可以将事件发送到其他事物的规则进行另一次更改,然后你再次被淹没.

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

所以——与其试图解决这个不可能的技术问题,不如让我们退后一步,问问你最初希望通过做所有这些来实现什么。这样,也许,我们可以将您带到您想去的地方:)

于 2011-02-10T09:17:34.917 回答
0

您忘记在每个发送键和延迟/等待期之间添加“DoEvents”,以便给它一些执行时间。

于 2020-06-19T07:34:04.310 回答
0

尝试 sendkeys "%{tab}" 切换窗口,但只保留 2 个活动窗口。

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

或尝试 appactivate window name, 1 然后 sleep 2000 ° 以留出时间使该窗口成为焦点

于 2016-10-09T05:41:58.363 回答