Vous devez déclarer explicitement le type de retour dans une macro VBA que vous exécutez dans un environnement 64 bits

Résumé

Lorsque vous essayez d’exécuter du code qui utilise des fonctions de rappel pour déclarer des API dans Microsoft Visual Basic pour Applications (VBA) dans une version 64 bits de Microsoft Office, le code échoue. Toutefois, ce code n’échoue pas sur une version 32 bits de Microsoft Office. Ce problème se produit car le type de retour doit être déclaré explicitement dans une application VBA 64 bits. 

Note Lorsque le type de retour n’est pas déclaré explicitement, la valeur est gérée à l’aide du type de données Variant.

Informations supplémentaires

Pour tester ce problème mentionné dans la section « Résumé », procédez comme suit :

  1. Ouvrez un document Word dans une version 64 bits de Microsoft Word 2010.
  2. Pour ouvrir l’Éditeur VBA, cliquez sur Visual Basic sous l’onglet Développeur du ruban.
  3. Pour créer un module dans l’éditeur VBA, procédez comme suit :
    1. Cliquez avec le bouton droit sur ce document sous l’arborescence project située en haut à gauche de l’éditeur VBA.
    2. Sélectionnez Insérer, puis cliquez sur Module.
    3. Un nouveau nœud de module s’affiche sous l’arborescence project et une fenêtre de code VBA s’ouvre pour le nouveau module.
    4. Copiez le code suivant, puis collez-le dans la fenêtre de code VBA pour le nouveau module.
Option Explicit
Dim iCounter As Integer
Dim lngTimerID As Long
Dim BlnTimer As Boolean

Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As Long, _
 ByVal nIDEvent As Long, _
 ByVal uElapse As Long, _
 ByVal lpTimerFunc As LongPtr) As Long

Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As Long, _
 ByVal nDEvent As Long) As Long

Sub TimerProc(ByVal hwnd As Long, _
 ByVal uMsg As Long, _
 ByVal idEvent As Long, _
 ByVal dwTime As Long)
iCounter = iCounter + 1
End Sub 

Private Sub ToggleTimer()
 If BlnTimer = False Then
 lngTimerID = SetTimer(0, 0, 200, AddressOf TimerProc)
 If lngTimerID = 0 Then
 MsgBox "Timer not created. Ending program"
 Exit Sub
 End If
 BlnTimer = True
 Else 
lngTimerID = KillTimer(0, lngTimerID)
 If lngTimerID = 0 Then
MsgBox "Could not kill the timer"
 End If
 BlnTimer = False
 MsgBox " Timer Count " & iCounter
 End If

End Sub

Sub Macro1()
 ToggleTimer
End Sub   
  1. Pour exécuter le code, cliquez sur Exécuter dans l’éditeur VBA ou sélectionnez la commande Exécuter sous-formulaire utilisateur dans le menu Exécuter . Ensuite, cliquez sur Exécuter Macro1 dans la boîte de dialogue qui s’affiche. 
  2. Ensuite, remplacez le code qui ressemble à ce qui suit d’une sous-procédure par une procédure function :
Sub TimerProc(ByVal hwnd As Long, _
 ByVal uMsg As Long, _
 ByVal idEvent As Long, _
 ByVal dwTime As Long)

iCounter = iCounter + 1
End Sub
After you have changed the Sub procedure to a Function procedure, the code resembles the following:

Function TimerProc(ByVal hwnd As Long, _
 ByVal uMsg As Long, _
 ByVal idEvent As Long, _
 ByVal dwTime As Long)

iCounter = iCounter + 1
End Function   
  1. Exécutez à nouveau le code, puis vous recevez l’erreur suivante :

Microsoft Word tente de récupérer vos informations. Cela peut prendre plusieurs minutes.

Le type de retour ne peut pas être du type de données Variant. Cette limitation s’applique uniquement aux fonctions de rappel dans VBA que vous exécutez dans un environnement 64 bits. Cette limitation ne s’applique pas aux instructions Declare pour l’appel de méthodes d’API externes. Dans VBA que vous exécutez dans un environnement 32 bits, vous pouvez utiliser une procédure Function qui utilise le type de données Variant et une sous-procédure pour les rappels d’API qui peuvent retourner une valeur Void, un type de données Entier de 16 bits ou un type de données Long de 32 bits. Par conséquent, les étapes mentionnées précédemment ne génèrent pas l’erreur si vous exécutez le code dans VBA dans un environnement 32 bits. Ce problème se produit en raison des modifications de pointeur dans VBA que vous exécutez dans un environnement 64 bits. Par conséquent, les fonctions de rappel doivent être déclarées explicitement à l’aide du type de retour correct dans l’environnement 64 bits. Ce comportement nécessite que TimerProc qui figure dans l’exemple mentionné précédemment soit déclaré en tant que sous-procédure et non en tant que procédure de fonction.