VBA Sleep Doesn't Work

后端 未结 7 1195
礼貌的吻别
礼貌的吻别 2020-12-03 10:57

I know I\'m doing something wrong here. I\'m trying to use the sleep function to delay my code, but I get \"Sub or Function not defined\" error. Any tips?

相关标签:
7条回答
  • 2020-12-03 11:18

    VBA does not have a Sleep function.

    You can import it from Kernel32.dll like this:

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

    Note that this will freeze the application.
    You can also call DoEvents in a While loop, which won't freeze the application.

    0 讨论(0)
  • 2020-12-03 11:22

    Everything I've tried seems to hang the application, including Application.Wait. This seems to work though:

    waitTill = Now() + TimeValue("00:15:00")
    
    While Now() < waitTill
        DoEvents
    Wend
    
    0 讨论(0)
  • 2020-12-03 11:33

    With this code Excel not freeze and the CPU usage is low:

    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sub Delay(s As Single)
        Dim TimeOut As Single
        TimeOut = Timer + s
        Do While Timer < TimeOut
            DoEvents
            Sleep 1 'With this line the CPU usage is 00 instead of 50 with an absolute error of +1ms and the latency of 1ms.
        Loop
    End Sub
    
    0 讨论(0)
  • 2020-12-03 11:35
    Application.Wait DateAdd("m", 10, Now) ' Wait for 10 Minutes
     Application.Wait DateAdd("s", 10, Now) ' wait for 10 seconds
    
    0 讨论(0)
  • 2020-12-03 11:37

    You can also pause the current macro context with Application.Wait T which won't block the whole process.

    0 讨论(0)
  • 2020-12-03 11:37

    Here's what you need for cross compatability with 32-bit and 64-bit Windows machines. The delay is in milliseconds, so use 1000 for a 1 second delay.

    First, put this above your other Subs/Functions in a module. On a 64-bit machine the line after "#Else" will be highlighted as if there is an error, but this isn't an issue. The code will compile and run.

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

    Now you can create a delay like this example with a 1.5 second delay:

    Sub ExampleWithDelay()
        Msgbox "This is a message before the delay."
        Sleep 1500    ' delay of 1,000 milliseconds or 1.5 seconds
        Msgbox "This is a message -AFTER- the delay."
    End Sub
    

    As noted by @SLaks, this freezes the application (preventing user input) but you can also call DoEvents in a While loop. See the example below. It runs for 10 seconds and allows user interaction.

    Every 1/10th of a second it updates the Excel status bar with:

    1. The address of the active cell

    2. A countdown

      Sub ExampleWithDelayInLoop()    ' for MS Excel
      
          Dim thisMessage As String
          Dim countdownText As String
          Dim i As Long
      
          Const TOTAL_SECONDS As Byte = 10
      
          For i = 1 To TOTAL_SECONDS * 10
      
              countdownText = Excel.WorksheetFunction.RoundUp(TOTAL_SECONDS - (i / 10), 0)
              thisMessage = "You selected " & Excel.ActiveCell.Address & Space$(4) & countdownText & " seconds remaining"
      
              ' Show the address of the active cell and a countdown in the Excel status\
              '   bar.
              If Not Excel.Application.StatusBar = thisMessage Then
                  Excel.Application.StatusBar = thisMessage
              End If
      
              ' Delay 1/10th of a second.
              '   Input is allowed in 1/10th second intervals.
              Sleep 100
              DoEvents
      
          Next i
      
      
          ' Reset the status bar.
          Excel.Application.StatusBar = False
      End Sub
      
    0 讨论(0)
提交回复
热议问题