web-dev-qa-db-fra.com

Comment faire une pause pour une durée déterminée? (Excel/VBA)

J'ai une feuille de calcul Excel qui a la macro suivante. Je voudrais faire une boucle à chaque seconde, mais je suis prêt si je peux trouver la fonction pour le faire. N'est-ce pas possible?

Sub Macro1()
'
' Macro1 Macro
'
Do
    Calculate
    'Here I want to wait for one second

Loop
End Sub
93
Keng

Utilisez la méthode Wait :

Application.Wait Now + #0:00:01#

ou (pour Excel 2010 et versions ultérieures):

Application.Wait Now + #12:00:01 AM#
114
Ben S

Ajoutez ceci à votre module

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Ou, pour les systèmes 64 bits, utilisez:

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

Appelez-le dans votre macro comme suit:

Sub Macro1()
'
' Macro1 Macro
'
Do
    Calculate
    Sleep (1000) ' delay 1 second

Loop
End Sub
58
Buggabill

à la place d'utiliser:

Application.Wait(Now + #0:00:01#)

je préfère:

Application.Wait(Now + TimeValue("00:00:01"))

parce que c'est beaucoup plus facile à lire après.

38
Achaibou Karim

cela fonctionne parfaitement pour moi. insérez n'importe quel code avant ou après la boucle "faire jusqu'à". Dans votre cas, placez les 5 lignes (time1 = & time2 = & "do Until") à la fin de votre boucle

sub whatever()
Dim time1, time2

time1 = Now
time2 = Now + TimeValue("0:00:01")
    Do Until time1 >= time2
        DoEvents
        time1 = Now()
    Loop

End sub
17
clemo

La déclaration de Sleep dans kernel32.dll ne fonctionnera pas dans Excel 64 bits. Ce serait un peu plus général:

#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
12
dbuskirk

Juste une version nettoyée du code de clemo - fonctionne dans Access, qui n'a pas la fonction Application.Wait.

Public Sub Pause(sngSecs As Single)
    Dim sngEnd As Single
    sngEnd = Timer + sngSecs
    While Timer < sngEnd
        DoEvents
    Wend
End Sub

Public Sub TestPause()
    Pause 1
    MsgBox "done"
End Sub
5
Brian Burns

Voici une alternative au sommeil:

Sub TDelay(delay As Long)
Dim n As Long
For n = 1 To delay
DoEvents
Next n
End Sub

Dans le code suivant, je fais clignoter un effet "clignotant" sur un bouton de commande pour y diriger les utilisateurs s'ils rencontrent des "problèmes", l'utilisation de "sommeil 1000" dans la boucle n'entraînait aucun clignotement visible, mais la boucle fonctionnait très bien.

Sub SpinFocus()
Dim i As Long
For i = 1 To 3   '3 blinks
Worksheets(2).Shapes("SpinGlow").ZOrder (msoBringToFront)
TDelay (10000)   'this makes the glow stay lit longer than not, looks Nice.
Worksheets(2).Shapes("SpinGlow").ZOrder (msoSendBackward)
TDelay (100)
Next i
End Sub
2
Reverus
Function Delay(ByVal T As Integer)
    'Function can be used to introduce a delay of up to 99 seconds
    'Call Function ex:  Delay 2 {introduces a 2 second delay before execution of code resumes}
        strT = Mid((100 + T), 2, 2)
            strSecsDelay = "00:00:" & strT
    Application.Wait (Now + TimeValue(strSecsDelay))
End Function
2
ITI

j'avais ceci fait pour répondre au problème:

Sub goTIMER(NumOfSeconds As Long) 'in (seconds) as:  call gotimer (1)  'seconds
  Application.Wait now + NumOfSeconds / 86400#
  'Application.Wait (Now + TimeValue("0:00:05"))  'other
  Application.EnableEvents = True       'EVENTS
End Sub
1
dave

La plupart des solutions présentées utilisent Application.Wait, qui ne prend pas en compte le temps (millisecondes) déjà écoulé depuis le début du compte actuel, donc ils ont une imprécision intrinsèque pouvant atteindre 1 seconde.

L'approche du minuteur est la meilleure solution}, mais vous devez prendre en compte la réinitialisation à minuit. Voici donc une méthode de veille très précise utilisant Timer:

'You can use integer (1 for 1 second) or single (1.5 for 1 and a half second)
Public Sub Sleep(vSeconds As Variant)
    Dim t0 As Single, t1 As Single
    t0 = Timer
    Do
        t1 = Timer
        If t1 < t0 Then t1 = t1 + 86400 'Timer overflows at midnight
        DoEvents    'optional, to avoid Excel freeze while sleeping
    Loop Until t1 - t0 >= vSeconds
End Sub

(UTILISER CECI POUR TESTER UNE FONCTION DE SOMMEIL:} _ (ouvrir la fenêtre de débogage: CTRL + G)

Sub testSleep()
    t0 = Timer
    Debug.Print "Time before sleep:"; t0   'Timer format is in seconds since midnight

    Sleep (1.5)

    Debug.Print "Time after sleep:"; Timer
    Debug.Print "Slept for:"; Timer - t0; "seconds"

End Sub
1
cyberponk

J'utilise habituellement la fonction Minuteur pour mettre l'application en pause. Insère ce code dans le tien

T0 = Timer
Do
    Delay = Timer - T0
Loop Until Delay >= 1 'Change this value to pause time for a certain amount of seconds

Les fonctions Wait et Sleep verrouillent Excel et vous ne pouvez plus rien faire avant la fin du délai. Les retards de boucle ne vous donnent pas une heure d'attente exacte.

J'ai donc fait cette solution de contournement un peu des deux concepts. Il boucle jusqu'à ce que l'heure soit à l'heure souhaitée.

Private Sub Waste10Sec()
   target = (Now + TimeValue("0:00:10"))
   Do
       DoEvents 'keeps Excel running other stuff
   Loop Until Now >= target
End Sub

Il vous suffit d'appeler Waste10Sec où vous avez besoin du délai

1
Maycow Moura

Essaye ça :

Threading.thread.sleep(1000)
0
DEV