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
これは答えというよりはコメントかもしれませんが、「コメント」することは許されていないようですので...
あなたがこれまでに得たのは驚くべきことです。たぶん、あなたはこの仕事を確実に行うことができないでしょう-期間。動作させるとすぐに、将来のリリースでAcrobat UIの動作が変更されるか、Windowsがイベントを他のものに送信できるルールに別の変更を加えると、再びうんざりします。 。
この場合におそらく遭遇しているのは、ユーザーが最初のアプリケーションとの対話で明らかに忙しいときに、アプリケーションが別のアプリケーションからフォーカスを盗むのを防止しようとしているWindowsです。 1つのアプリケーションのボタンで一時ファイルにデータを書き込み、MS Wordを開いて編集するなど、同じ種類の問題が発生します。 Windowsは、現在のアプリのボタンをクリックしただけなので、フォーカスが現在のアプリからMSWordに移動するのを防ぎます。
つまり、この不可能な技術的な問題を解決しようとするのではなく、一歩下がって、これらすべてを実行することで最初に何を達成したいと思っていたかを尋ねましょう。そのようにして、おそらく、私たちはあなたが行こうとしているところにあなたを連れて行くことができます:)
私はこの質問が古いことを知っています、しかし私はこれと同じ問題に遭遇しました、しかし私は選ばれた答えが正しいものであるとは思いません。
AppActivateを呼び出すと、スクリプトは停止し、ターゲットアプリケーションが終了するのを待ちます。アプリケーションが終了した後、スクリプトは続行されます。この問題の解決策は見当たりません。
編集:
バッチファイルを使用してAppActivateコマンドのCSCRIPTを呼び出していますが、厳密にVBSファイルを使用していることに気付きました。新しいウィンドウとしてCMD
を呼び出し、引数としてCSCRIPT //NoLogo //B WScript.CreateObject("WSCript.Shell").AppActivate("Window Name")
を渡してみて、それが問題を回避するかどうかを確認してください。
同様に、SendKeysを使用できるように、シェルコマンドで開いたPDFドキュメントでAppActivateを使用しようとしていました。常に実行時エラー「5」が生成されます。私の解決策は、最終的にはAppActivateをまったく使用しないことでした。実際、ドキュメントを開くと、とにかく最前線になります。問題は、SendKeysステートメントがShellコマンドの直後に実行されるが、PDFを開くのに1〜2秒かかることです。私の解決策は、sendkeysステートメントを実行する前にコードを数秒間一時停止することです。
私はpootleflumpの時間遅延curtosyを使用しました。こちらのスレッドをチェックしてください: http://www.dbforums.com/Microsoft-access/1219379-time-delay-vba.html
さまざまなフォーラムで何時間も調査した結果、AdobeReaderでAdobeライブラリのオブジェクトと関数を使用できないことがわかりました。残された唯一の実行可能なオプションは、シェルコマンドを使用して、AdobeReaderのファイルメニューで使用可能な「テキストとして保存」オプションを使用することでした。ショートカットキーは 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
Sendkeys "%{tab}"を試してウィンドウを切り替えますが、アクティブなウィンドウは2つだけにしておきます。
または、sendkeys {Tab}の後でのみappactivateを試して、switchibg windowscmdの前にテキスト入力ボックスが選択されないようにします。
または、ウィンドウ名をappactivateしてみてください。1、2000°スリープして、ウィンドウにフォーカスを合わせる時間を確保します。