18 votes

Excel ne complète pas la macro après avoir ouvert un autre classeur

Je suis en train d'essayer de faire en sorte que VBA exécute les commandes

sImportFilePath = Application.GetOpenFilename(FileFilter:= _
"Fichiers Excel (*.xls), *.xls", Title:="Choisir le fichier source")
Application.Workbooks.Open(sImportFilePath)
sImportFileName = FunctionGetFileName(sImportFilePath)

Et ils fonctionnent lorsque je parcours la fonction, mais lorsque j'utilise le raccourci Ctrl+Maj+F ou tout autre raccourci, la commande Application.Workbooks.Open fonctionne mais elle navigue vers le nouveau document Excel, puis ne fait rien. Cependant, lorsque j'ouvre les "Macros" dans l'onglet développeur, que je sélectionne ma macro, et que je clique sur "Exécuter", tout se déroule bien.

24voto

psubsee2003 Points 4116

Je suis en fait tombé sur ce problème exact moi-même et j'ai enfin trouvé une solution à mon problème.

C'est le bouton Shift dans le raccourci clavier que vous utilisez pour appeler votre code.

Apparemment, il existe une fonctionnalité dans Excel spécifiquement conçue pour empêcher l'exécution du code lorsqu'un classeur est ouvert et que la touche Shift est pressée, mais malheureusement cela influence aussi l'ouverture des classeurs avec la méthode Workbook.Open via VBA. Cela a été mentionné dans l'article KB 555263, s'appliquant à Excel 2000 et 2003, mais j'ai rencontré le même problème dans Excel 2010, donc j'imagine qu'il impacte aussi la version 2007.

Cela se produit spécifiquement lorsque vous essayez d'ouvrir un classeur via du code très tôt dans le programme. Si l'appel Workbook.Open est atteint dans le code avant d'avoir eu suffisamment de temps pour relâcher complètement le bouton Shift, Excel interprète cela comme une tentative de bloquer l'exécution du code et interrompt le processus. Et il n'y a aucun message d'erreur ou quoi que ce soit que j'ai trouvé. Cela s'arrête simplement brusquement.

La solution/le correctif est de forcer le code à attendre que la touche Shift soit relâchée avant de donner la commande Workbook.Open.

D'après l'article, il suffit d'ajouter ce code à votre macro et cela devrait fonctionner :

'Déclaration API
Declare Function GetKeyState Lib "User32" (ByVal vKey As Integer) As Integer
Const SHIFT_KEY = 16

Function ShiftPressed() As Boolean
'Retourne True si la touche Shift est pressée
    ShiftPressed = GetKeyState(SHIFT_KEY) < 0
End Function

Sub Demo()
    Do While ShiftPressed()
        DoEvents
    Loop
    Workbooks.Open Filename:="C:\MonChemin\MonFichier.xlsx"
End Sub

(REMARQUE : Ce code est pour les versions 32 bits d'Excel. Les versions 64 bits devront utiliser l'attribut PtrSafe sur l'instruction Declare).

Si vous ne voulez pas ajouter le code supplémentaire, alors vos seules autres options sont de ne pas utiliser Ctrl+Shift+Une Lettre pour lancer une macro, ou de placer la commande Workbook.Open plus tard dans la macro (pas juste au début) pour vous donner le temps de relâcher le bouton Shift après l'avoir démarré.

4voto

Peter Heijnen Points 41

Il suffit d'ajouter un seul appel à "DoEvents" avant d'appeler Workbooks.Open pour que ça marche déjà. Ainsi, l'extrait suivant fonctionnera :

DoEvents
Workbooks.Open Filename:="C:\MyPath\MyFile.xlsx"

1voto

Joe Nagy Points 11

Question avez-vous déjà eu une ligne de code sélectionnant plusieurs onglets avant cette ligne de code ? J'ai découvert que c'est un peu comme si vous mainteniez la touche Maj enfoncée tout le temps qu'ils sont sélectionnés. Pour résoudre cela, j'ai eu la macro de désassembler (sélection unique) un onglet et la macro a commencé à fonctionner ensuite.

0voto

Mind Driver Points 1

Un simple contournement qui a fonctionné pour moi est d'assigner la VBA à une touche de raccourci sans majuscule. Je ne suis pas fan de le faire car il y a beaucoup plus de conflits avec les raccourcis Excel par défaut. Mais il y en a quelques-uns disponibles à partir d'Excel 2010 basés sur cet article : Ctrl+e, Ctrl+j, Ctrl+m, Ctrl+q.

0voto

vkc34 Points 1

Solution temporaire trouvée sur un forum français : utilisez le ForEachWinDoEvents ci-dessous avant d'activer le classeur de votre choix.

Sub Test()
    Application.ScreenUpdating = False
    Set w1 = Workbooks.Add(xlWBATWorksheet)
    Set w2 = Workbooks.Add(xlWBATWorksheet)
    Set w3 = Workbooks.Add(xlWBATWorksheet)
    Application.ScreenUpdating = True
    ForEachWinDoEvents
    w2.Activate
End Sub

Sub ForEachWinDoEvents()
Dim win As Window
  For Each win In Application.Windows
    DoEvents
  Next win
End Sub

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X