🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Sleep dans Excel — l'appel d'API Windows, le piège PtrSafe 64 bits, et Wait vs Sleep

|

VBA Sleep dans Excel — l'appel d'API Windows, le piège PtrSafe 64 bits, et Wait vs Sleep

TL;DRSleep ne fait pas partie de VBA. C'est une fonction d'API Windows qui met votre macro en pause pendant un nombre de millisecondes, et vous devez la déclarer avant de pouvoir l'appeler. Sur Excel 64 bits, cette déclaration doit porter l'attribut PtrSafe, enveloppée dans une garde #If VBA7 pour qu'elle compile encore partout :

#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

Sub PauseQuarterSecond()
    Sleep 250            ' 250 millisecondes = un quart de seconde
End Sub

On se tourne vers Sleep quand Application.Wait ne suffit pas — quand il faut une pause d'une fraction de seconde, pas d'une seconde entière. Et la toute première chose qui arrive est une erreur de compilation, car Sleep n'est pas du tout une commande VBA : elle vit dans Windows. Ce guide repose sur une seule idée — Sleep est une pause en millisecondes que vous empruntez au système d'exploitation — car elle explique la déclaration, le piège 64 bits, et pourquoi Sleep ne peut toujours pas vous offrir une pause réactive.

Ce que vous allez apprendre

  • Le modèle mental — Sleep est une fonction kernel32 de Windows que vous empruntez, pas un mot-clé VBA
  • Le piège PtrSafe 64 bits — l'erreur de compilation exacte et le correctif #If VBA7 exact
  • Des millisecondes, pas des secondes — la précision inférieure à la seconde qui est toute la raison d'utiliser Sleep
  • Pourquoi « millisecondes » ne veut pas dire « précis » — le plancher d'environ 15 ms de l'ordonnanceur de l'OS
  • Pourquoi Sleep fige quand même Excel, et quand utiliser Wait ou une boucle DoEvents à la place

Le modèle mental : une pause empruntée à Windows

Application.Wait est l'outil propre à Excel. Sleep ne l'est pas — il appartient à Windows, dans une bibliothèque système appelée kernel32. Pour l'utiliser, vous sortez de VBA avec une instruction Declare qui dit, en substance : « il existe une fonction nommée Sleep là-bas dans kernel32 ; voici sa forme ; laisse-moi l'appeler. » C'est seulement alors que vous pouvez écrire Sleep 250.

Cet « emprunt à Windows » est le modèle mental, et tout ce qui est pénible avec Sleep en découle. Un mot-clé VBA natif fonctionnerait sans plus. Une fonction d'API empruntée doit être déclarée, doit respecter la convention d'appel du système d'exploitation et — c'est crucial — doit être déclarée différemment sur Windows 32 bits et 64 bits. C'est sur ce dernier point que presque tout le monde se bloque.

Le piège PtrSafe 64 bits : l'erreur et le correctif

C'est le problème numéro un de Sleep, et c'est la raison pour laquelle une macro qui « marchait sur l'ancien ordinateur » refuse soudain de s'exécuter. La déclaration classique que vous trouverez dans le vieux code et les vieux messages de forum est :

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)   ' style d'avant 2010

Exécutez cela dans un Excel 64 bits moderne et, avant qu'une seule ligne ne s'exécute, VBA s'arrête avec :

Compile error: The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.

Le correctif a deux volets. D'abord, ajoutez le mot-clé PtrSafe, qui indique à VBA que la déclaration a été revue pour la sûreté des pointeurs 64 bits. Ensuite, enveloppez-la dans un bloc de compilation conditionnelle #If VBA7 pour que le même fichier compile encore sur les anciennes versions d'Excel antérieures à PtrSafe :

#If VBA7 Then
    ' Excel 2010 et ulterieur - securise en 64 bits
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    ' Excel 2007 et anterieur - le mot-cle PtrSafe n'existe pas
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

#If VBA7 est évalué au moment de la compilation, pas de l'exécution, si bien que chaque version d'Excel ne voit jamais que la seule déclaration qu'elle comprend. Placez ce bloc en tête d'un module standard, au-dessus de toute procédure, et Sleep compile et s'exécute sur tout Excel moderne. Si vous ne visez jamais que l'Excel 365 64 bits, la ligne PtrSafe suffit à elle seule — mais la version protégée est le copier-coller sûr.

Des millisecondes, pas des secondes — la raison d'être de Sleep

Sleep prend des millisecondes. Sleep 250, c'est un quart de seconde ; Sleep 1000, une seconde ; Sleep 50, un cinquantième. C'est toute la raison de préférer Sleep à Application.Wait, qui ne peut faire de pause qu'en secondes entières. Si vous devez brider une boucle à quelques passages par seconde, espacer des requêtes d'API ou attendre un court instant que quelque chose se stabilise, Sleep est l'outil à la bonne résolution.

Do
    ' ... verifier si le fichier d'export est apparu ...
    If Dir(exportPath) <> "" Then Exit Do
    Sleep 200        ' interroger cinq fois par seconde au lieu de marteler le disque
Loop

Mais « millisecondes » ne veut pas dire « précis »

Ne confondez pas des unités fines et une précision fine. Windows ordonnance les threads sur un tic d'environ 15,6 millisecondes, donc Sleep 1 ne dort pas une milliseconde — il dort jusqu'au prochain tic de l'ordonnanceur, généralement autour de 15 ms. Sleep garantit « au moins cette durée », jamais « exactement cette durée », et la pause réelle est arrondie au grain de l'ordonnanceur. C'est très bien pour brider et cadencer, où vous voulez seulement « à peu près à cette fréquence ». C'est le mauvais outil s'il vous faut un minutage précis ou une mesure exacte — pour mesurer le temps écoulé, utilisez Timer ; pour un minutage de haute précision, vous descendriez à QueryPerformanceCounter.

Sleep fige quand même Excel

Voici le piège que Sleep partage avec Application.Wait : pendant qu'il met en pause, Excel est figé. Sleep immobilise l'unique thread d'Excel pour toute la durée et ne traite pas la file de messages, si bien que l'écran ne se repeint pas, les clics ne sont pas gérés, et un Sleep assez long — ou beaucoup de petits dans une boucle — fait passer la fenêtre en « Ne répond pas ». La précision inférieure à la seconde n'y change rien ; une pause est une pause, et un thread bloqué est un Excel figé.

Donc Sleep, comme Wait, est le mauvais outil quand le but de la pause est de laisser l'utilisateur voir ou faire quelque chose. Une pause où Excel reste vivant est une boucle qui cède la main avec DoEvents :

' Cadence sous la seconde et reactive - Excel reste vivant entre les battements
Dim nextBeat As Double
nextBeat = Timer + 0.25
Do While Timer < nextBeat
    DoEvents
Loop

L'avis honnête : Wait, Sleep ou une boucle DoEvents

Alignez les trois selon ce dont vous avez réellement besoin :

  • Une pause en secondes entières, sans histoiresApplication.Wait Now + TimeValue(...). Pas de Declare, pas de PtrSafe, rien à rater. C'est le premier réflexe pour « attendre environ 2 secondes ».
  • Une pause inférieure à la secondeSleep, car Application.Wait ne peut pas descendre sous la seconde. Acceptez le cérémonial Declare/PtrSafe comme le prix de la résolution à la milliseconde.
  • Une pause où Excel doit rester réactif — une boucle DoEvents, car Wait comme Sleep figent la fenêtre. C'est celle dont on a le plus souvent besoin et vers laquelle on se tourne le moins souvent.

Le défi : n'ajoutez pas un Sleep « au cas où » pour ralentir une macro. Si une macro se comporte mal sans pause artificielle, la pause cache généralement un vrai bug — une valeur lue avant d'être prête, un événement déclenché deux fois — et le correctif honnête s'attaque à cela, pas à un Sleep 500 saupoudré par-dessus.

Comment ExcelMaster aide

La déclaration de Sleep est exactement le genre de code passe-partout facile à rater et fastidieux à réussir : la chaîne Lib "kernel32", l'argument ByVal, l'attribut PtrSafe, la garde #If VBA7, puis le jugement à porter sur le fait que Sleep soit même l'outil voulu plutôt que Application.Wait ou une boucle DoEvents.

ExcelMaster écrit pour vous la déclaration correcte et sûre en 64 bits et, surtout, retient la bonne construction d'attente pour ce que vous avez décrit. Demandez « interroger un fichier toutes les 200 ms » et il vous donne une boucle Sleep protégée ; demandez « faire une pause mais en me laissant annuler » et il vous donne plutôt une boucle DoEvents — vous ne livrez donc jamais le Declare d'avant 2010 qui plante sur Excel 64 bits, et vous ne figez jamais Excel alors que vous vouliez le garder vivant.

Questions fréquentes

Comment utiliser Sleep en VBA Excel ?

Déclarez-le une fois en tête d'un module standard, puis appelez-le avec une valeur en millisecondes. Utilisez la forme sûre en 64 bits : #If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) (avec un Declare simple dans la branche #Else pour les vieux Excel). Ensuite, Sleep 250 met la macro en pause pendant 250 millisecondes — un quart de seconde.

Pourquoi mon Declare de Sleep provoque-t-il une erreur de compilation sur Excel 64 bits ?

Parce que l'ancien style de déclaration est antérieur à Office 64 bits. L'Excel 64 bits moderne exige l'attribut PtrSafe sur chaque instruction Declare, et sans lui vous obtenez « The code in this project must be updated for use on 64-bit systems… mark them with the PtrSafe attribute. » Ajoutez PtrSafe après Declare, et enveloppez la ligne dans un bloc #If VBA7 pour qu'elle compile aussi sur les anciens Excel.

Quelle est la différence entre Sleep et Application.Wait ?

Sleep est un appel d'API Windows que vous devez déclarer ; il met en pause pendant un nombre de millisecondes et offre une précision inférieure à la seconde. Application.Wait est intégré à Excel, ne demande aucune déclaration, et met en pause jusqu'à un moment de l'horloge avec une résolution à la seconde entière. Utilisez Sleep quand il vous faut plus fin que la seconde, et Application.Wait pour de simples pauses en secondes entières. Les deux figent Excel pendant l'attente.

Sleep rend-il Excel non réactif ?

Oui. Sleep bloque l'unique thread d'Excel pendant toute la pause et ne traite pas les messages, si bien que la fenêtre ne peut ni se repeindre ni gérer les clics et peut afficher « Ne répond pas ». Si vous avez besoin qu'Excel reste réactif pendant une pause — pour la progression ou un bouton Annuler — utilisez une boucle qui appelle DoEvents au lieu de Sleep.

Sleep est-il précis à la milliseconde ?

Non. Windows ordonnance les threads sur un tic d'environ 15,6 ms, donc Sleep 1 met en pause à peu près 15 ms, et Sleep ne garantit que « au moins cette durée ». C'est très bien pour brider et cadencer, mais pas pour un minutage précis. Pour mesurer combien de temps prend du code, utilisez plutôt la fonction Timer.

Testé dans

Testé dans : Excel 365 (Windows 11, 64 bits), VBA 7.1 — dernière vérification le 19/08/2026.

Guides associés : VBA Wait · VBA Timer · VBA DoEvents · VBA On Error · VBA ScreenUpdating