web-dev-qa-db-fra.com

Utilisation de la commande AppActivate et Sendkeys dans le shell VBA

Je veux passer d’une application à l’autre avec la commande Shell dans VBA. J'utilise SendKeys pour exécuter des tâches dans le processus A, puis pour passer au processus B, puis pour traiter A puis pour traiter B. première itération. Lorsque j'utilise AppActivate pour revenir au processus B, cela rétablit le focus sur le processus B. Cependant, il ignore les commandes suivantes de SendKeys.

Exemple de code:

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
elbillaf

Cela pourrait être plus un commentaire qu'une réponse, mais je ne semble pas être autorisé à "commenter", alors ...

C'est incroyable que tu sois aussi loin que toi. Les chances sont, vous ne serez jamais capable de faire ce travail fiable - point. Dès que cela fonctionne, quelque chose change sur le comportement de l'interface utilisateur d'Acrobat dans une version ultérieure, ou Windows modifie de nouveau les règles pour ce qui peut envoyer des événements à d'autres objets, puis vous êtes redirigé. .

Ce que vous rencontrez probablement dans ce cas-ci, c'est que Windows essaie d'empêcher une application de dérober le focus à une autre lorsqu'un utilisateur est apparemment occupé à interagir avec le premier. Vous rencontrez le même type de problèmes lorsque vous essayez de faire des choses, par exemple, avoir un bouton dans une application pour écrire des données dans un fichier temporaire et ouvrir MS Word pour le modifier. Windows empêche le transfert du focus de l'application actuelle vers MS Word, car vous venez de cliquer sur un bouton de l'application actuelle.

Alors, au lieu d'essayer de résoudre ce problème technique impossible, prenons un peu de recul et demandons ce que vous espériez accomplir à l'origine en faisant tout cela. De cette façon, nous pourrons peut-être vous mener là où vous essayez d'aller :)

2
Steve Jorgensen

Je sais que cette question est ancienne, mais j'ai rencontré le même problème, mais je ne pense pas que la réponse choisie soit la bonne.

Lorsque vous appelez AppActivate, le script s'arrête, en attendant la fin de l'application cible. Une fois l'application terminée, le script continue. Je ne vois aucune solution à ce problème.

MODIFIER:

J'utilise un fichier de commandes pour appeler CSCRIPT pour la commande AppActivate et je remarque que vous utilisez strictement un fichier VBS. Essayez d'appeler CMD en tant que nouvelle fenêtre et transmettez CSCRIPT //NoLogo //B WScript.CreateObject("WSCript.Shell").AppActivate("Window Name") en tant qu'argument afin de voir si cela contourne le problème.

3
Mechaflash

De même, j'essayais d'utiliser AppActivate sur un document pdf que j'avais ouvert avec une commande Shell afin de pouvoir utiliser SendKeys dessus. Il générerait toujours une erreur d’exécution «5». Ma solution a finalement été de ne PAS utiliser AppActivate du tout. En fait, ouvrir le document le met au premier plan de toute façon. Le problème est que l'instruction SendKeys s'exécute immédiatement après la commande Shell, mais que le fichier PDF nécessite une seconde ou deux pour s'ouvrir. Ma solution consiste à suspendre le code pendant quelques secondes avant d'exécuter l'instruction sendkeys.

J'ai utilisé une courte durée de crotte de pootle. Découvrez le fil ici: http://www.dbforums.com/Microsoft-access/1219379-time-delay-vba.html

2
cloudyjudgement

Après des heures de recherche sur divers forums, je me suis rendu compte que je ne serais pas en mesure d'utiliser les objets et les fonctions de la bibliothèque Adobe avec Adobe Reader. La seule option viable restante consistait à utiliser les commandes Shell pour utiliser l'option "enregistrer en tant que texte" disponible dans le menu Fichier de Adobe Reader. La touche de raccourci est Alt+f+a+x+s. Je les ai implémentées dans le code ci-dessous, ce qui a parfaitement fonctionné, bien que je devais insérer des délais dans certaines étapes.

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
2
Barun Rai

Essayez Sendkeys "% {tab}" Pour changer de fenêtre Mais ne conservez que 2 fenêtres actives.

ou essayez uniquement après sendkeys {Tab} afin que la zone de saisie de texte ne soit pas sélectionnée avant switchibg windows cmd.

ou essayez avec essayez avec appactivate window name, 1 puis dormez 2000 ° pour avoir le temps de mettre au point cette fenêtre.

0
Sahara_trip