Использование AppActivate и Sendkeys в команде оболочки VBA

Я хочу переключаться между приложениями с помощью команды оболочки в VBA. Я использую SendKeys, чтобы делать вещи в процессе A, а затем перейти к процессу B, а затем к процессу 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 FilesAdobeAcrobat 9.0AcrobatAcrobat.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

5 ответов


Это может быть скорее комментарий, чем ответ, но мне, похоже, не разрешено "комментировать", поэтому...

удивительно, что Вы зашли так далеко. Скорее всего, вы никогда не сможете сделать эту работу надежной ... и точка. Как только вы сделаете это работать, что-то изменится о том, как Acrobat UI ведет себя в будущем выпуске, или Windows внесет еще одно изменение в правила для того, что вещи могут отправлять события в то, что другие вещи, а затем вы обливаются снова.

то, с чем вы, вероятно, сталкиваетесь в этом случае, - это Windows, пытающаяся предотвратить приложение, крадущее фокус у другого, когда пользователь, по-видимому, занят взаимодействием с первым. Вы видите те же проблемы, пытаясь сделать такие вещи, как иметь кнопку в одном приложении, записать данные во временный файл и открыть MS Word для его редактирования. Windows предотвращает перенос фокуса из текущего приложения в MS Word, поскольку вы только что нажали кнопку в текущее приложение.

Итак -- вместо того, чтобы пытаться решить эту невозможную техническую проблему, давайте сделаем шаг назад и спросим, чего вы изначально надеялись достичь, делая все это. Таким образом, возможно, мы сможем получить вас туда, куда вы пытаетесь пойти:)


Я знаю, этот вопрос старый, но я столкнулся с этой же проблемой, но я не думаю, что ответ, который был выбран правильный.

когда вы вызываете AppActivate, скрипт останавливается, ожидая завершения целевого приложения. После завершения работы приложения сценарий продолжается. Я не вижу решения этой проблемы.

EDIT:

Я использую пакетный файл для вызова CSCRIPT для команды AppActivate, и я замечаю, что вы строго используете VBS файл. Попробуйте позвонить CMD как новое окно и пройти CSCRIPT //NoLogo //B WScript.CreateObject("WSCript.shell").AppActivate("Window Name") в качестве аргумента, и посмотреть, если это обходит эту проблему.


аналогично, я пытался использовать AppActivate в pdf-документе, который я открыл с помощью команды оболочки, чтобы я мог использовать SendKeys на нем. Он всегда будет генерировать ошибку времени выполнения '5'. Мое решение, в конечном итоге, было не использовать AppActivate вообще, на самом деле открытие документа выводит его на передний план. Проблема в том, что оператор SendKeys выполняется сразу после команды оболочки, но pdf требуется секунда или две, чтобы открыть. Мое решение-приостановить код на пару секунд перед исключением оператора sendkeys.

Я использовал временную задержку curtosy pootle flump. Проверьте поток здесь: http://www.dbforums.com/microsoft-access/1219379-time-delay-vba.html


после нескольких часов исследований на различных форумах я мог понять, что я не смогу использовать объекты и функции библиотеки Adobe с Adobe Reader. Единственным жизнеспособным вариантом оставалось использовать команды оболочки для использования опции "сохранить как текст", доступной в меню "Файл" 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

попробовать sendkeys " %{tab}" переключение окон но тогда хранить только 2 активных окна.

или попробовать appactivate только после sendkeys {Tab}, так что поле ввода текста Не выбран до switchibg Windows cmd.

или попробовать попробуйте appactivate имя окна, 1 затем спать 2000 °, чтобы время, чтобы привести это окно в фокус