2011-01-12 27 views
6

Voglio passare avanti e indietro tra l'applicazione con il comando shell in VBA. Sto usando SendKeys per fare cose nel processo A quindi passare al processo B, quindi per elaborare A, quindi elaborare B. Funziona perfettamente per la prima iterazione. Quando uso AppActivate per tornare al processo B, in realtà passa a focus focus sul processo B. TUTTAVIA, ignora i comandi successivi da SendKeys.Utilizzo di AppActivate e Sendkeys nel comando shell VBA

codice

Esempio:

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 

risposta

2

Questo potrebbe essere più di un commento di una risposta, ma non mi sembra di poter "commento", quindi ...

È incredibile che si sei arrivato fino a te. Le probabilità sono, non sarai mai in grado di fare questo lavoro in modo affidabile - periodo. Non appena lo fai funzionare, qualcosa cambierà in che modo l'interfaccia utente di Acrobat si comporterà in una versione futura, o Windows apporterà un'altra modifica alle regole per ciò che le cose possono inviare eventi a ciò che altre cose, e poi tu verrai di nuovo .

In questo caso, in questo caso, probabilmente stai cercando di impedire a un'applicazione di rubare l'attenzione da un'altra quando un utente è apparentemente occupato a interagire con il primo. Si vedono gli stessi tipi di problemi che cercano di fare cose come avere un pulsante in un'applicazione che scrive i dati in un file temporaneo e aprire MS Word per modificarlo. Windows impedisce allo stato attivo di trasferire via dall'app corrente e passare a MS Word perché è stato semplicemente fatto clic su un pulsante nell'app corrente.

Quindi, invece di cercare di risolvere questo problema tecnico impossibile, facciamo un passo indietro e chiediamo che cosa stavi originariamente sperando di ottenere facendo tutto questo. In questo modo, forse, possiamo portarti dove stai cercando di andare :)

+0

Quello che ho è un gruppo (più di 1000) di file PDF che hanno il testo che voglio analizzare. Parte del testo è in forma libera e inutilizzabile. Altre parti del testo sono formattate in modo abbastanza coerente e posso ottenere tali informazioni e inserirle in un database (foglio di calcolo Excel) per analisi successive. Dopo che i dati sono stati inseriti in un file di testo, analizzo uno script perl per ottenere le cose che voglio e creare un CSV. Questo è un modo schifoso di farlo - per i motivi che offri, anche perché è esteticamente brutto e non sembra funzionare in modo coerente in tutti i casi. – elbillaf

+0

Il metodo generale funziona se il pdf è solo una pagina, ma per pagine multiple, acrobat seleziona solo una pagina su un^A (da sendkeys) quindi devo andare avanti e indietro - che non sembra funzionare. Sono stato in grado di aggirare questo problema per il mio compito attuale, ma mi piacerebbe un metodo generale per affrontare questo tipo di problema in modo che i metodi futuri non siano così irritanti. – elbillaf

+1

Si può usare qualcosa come http://www.pdf2txt.com/ invece di provare ad automatizzare la GUI di Acrobat? –

3

So che questa domanda è vecchia, ma ho incontrato questo stesso problema, ma non penso che la risposta sia stata scelta è quello giusto.

Quando si chiama AppActivate, lo script si interrompe, in attesa che l'applicazione di destinazione venga chiusa. Dopo che l'applicazione è terminata, lo script continua. Non vedo alcuna soluzione a questo problema.

EDIT:

io uso un file batch per chiamare CSCRIPT per il comando AppActivate, e ho notato che si sta rigorosamente utilizza un file VBS. Prova a chiamare CMD come una nuova finestra e passa CSCRIPT //NoLogo //B WScript.CreateObject("WSCript.shell").AppActivate("Window Name") come argomento, e vedi se questo elude il problema.

+0

Ho già finito quel progetto e non sto più lavorando su questo problema; tuttavia, questo genere di cose affiora ogni pochi anni, quindi terrò questo a mente per il prossimo giro. grazie, TFF. – elbillaf

2

Analogamente, stavo cercando di utilizzare AppActivate su un documento PDF che avevo aperto con un comando di shell in modo che potessi usare SendKeys su di esso. Genererebbe sempre errore Run Time '5'. La mia soluzione, infine, è stata quella di NON utilizzare AppActivate affatto, infatti aprire il documento lo porta comunque in primo piano. Il problema è che l'istruzione SendKeys viene eseguita immediatamente dopo il comando della shell ma il pdf necessita di un secondo o due per essere aperto. La mia soluzione è di mettere in pausa il codice per un paio di secondi prima di escutare l'istruzione sendkeys.

Ho usato un tempo di ritardo puntinoso del crollo di un pootle. Controlla il thread qui: http://www.dbforums.com/microsoft-access/1219379-time-delay-vba.html

+0

che ha funzionato per me. Ho usato un ritardo di temporizzazione come: Application.Wait Now + TimeValue ("00: 00: 2") – Selrac

2

Dopo ore di ricerca su vari forum, ho potuto capire che non sarei in grado di utilizzare oggetti e funzioni della libreria Adobe con Adobe Reader. L'unica opzione valida rimasta era usare i comandi della shell per usare l'opzione "salva come testo" disponibile nel menu File di Adobe Reader.Il tasto di scelta rapida è Alt +f + un + x + s. Li ho implementati nel codice qui sotto che ha funzionato perfettamente, anche se mi è stato richiesto di inserire ritardi in alcuni passaggi.

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 
0

Prova SendKeys "% {tab}" per passare da una finestra ma poi tenere solo 2 finestre attive.

o provare appattivare solo dopo i tasti di invio {Tab} in modo che la casella di testo non sia selezionata prima di passare a cmd di windows.

o cercare provare nome della finestra AppActivate, 1 poi dormire 2000 ° per dare il tempo di portare quella finestra a fuoco

Problemi correlati