【问题标题】:VBA Sleep Doesn't WorkVBA 睡眠不起作用
【发布时间】:2010-04-29 13:32:30
【问题描述】:

我知道我在这里做错了什么。我正在尝试使用 sleep 功能来延迟我的代码,但我收到“未定义子或功能”错误。有什么建议吗?

【问题讨论】:

    标签: vba sleep


    【解决方案1】:

    VBA 没有Sleep 函数。

    您可以像这样从 Kernel32.dll 导入它:

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

    请注意,这将冻结应用程序。
    您也可以在While 循环中调用DoEvents,这不会冻结应用程序。

    【讨论】:

    • 我在代码中的什么地方放置了声明?我已经尝试将它粘贴在我正在处理的潜艇的外部和内部,但两次都出现错误。
    • 哦,哎呀,我正试图将它放入一个 excel 对象中(我很傻)。我把它放在一个模块中,现在它可以工作了。非常感谢!我检查了你的答案。
    • 尽管有挂起应用程序的问题,但我更喜欢这种方法,因为循环方法使用过多的 CPU。
    • @kalengi:你应该使用异步。
    • @SLaks 与睡眠异步,或者你是什么意思?
    【解决方案2】:

    我尝试过的一切似乎都会挂起应用程序,包括 Application.Wait。不过这似乎可行:

    waitTill = Now() + TimeValue("00:15:00")
    
    While Now() < waitTill
        DoEvents
    Wend
    

    【讨论】:

    • 我喜欢这个,而且效果很好。只有一个例外。我找不到 500 毫秒的方法……所以 1 秒是最短等待时间。有没有办法做到不到 1 秒?
    • 如果您想要更高的分辨率,您可以在 kernel32.dll 中使用 GetSystemTime:freevbcode.com/ShowCode.asp?ID=1618 或者如果在 Excel 中,您可以调用电子表格 now() 函数(作为 VBA 中的 [now()])也有更高的分辨率:groups.google.com/forum/#!topic/…
    • 在 Excel 中,您可以在对 Now 的调用周围使用方括号来获取具有亚秒精度的 Worksheet 函数版本。 [Now()]
    • 更优雅的解决方案之一 :)
    【解决方案3】:

    您也可以使用Application.Wait T 暂停当前宏上下文,这不会阻塞整个过程。

    【讨论】:

    • 这仅适用于Excel.Application。其他 Office 应用程序对象模型不存在 Wait 方法。
    【解决方案4】:
    Application.Wait DateAdd("m", 10, Now) ' Wait for 10 Minutes
     Application.Wait DateAdd("s", 10, Now) ' wait for 10 seconds
    

    【讨论】:

    • 欢迎来到 Stack Overflow!感谢您发布您的答案!请务必仔细阅读FAQ on Self-Promotion。另请注意,每次链接到自己的网站/产品时,都要求发布免责声明。
    • @AndrewBarber:查看链接,它看起来不像 Babu 的网站,而是对 SO 有用的读物​​。为什么要删除它?
    • @PeterAlbert 这是巴布的网站。他们最近经常发送垃圾邮件(他们的多个答案被作为垃圾邮件删除,因为他们甚至没有包含这么多信息),并且它在他们的个人资料中。
    • @AndrewBarber - 感谢您的信息!我不得不承认,我不会注意到!
    • "m" = 月;如果你想要分钟使用“n”
    【解决方案5】:

    暂停应用程序 10 秒。

    Application.Wait (Now + TimeValue("0:00:10"))
    

    【讨论】:

    • 您好,您有什么理由可以想到为什么此功能在 MS Outlook 中不可用?出于某种原因,Alt+F11 VBA 编辑器似乎没有显示它,并且当我在 Outlook 消息的函数中运行它时(来自规则)它不起作用。谢谢!
    【解决方案6】:

    使用此代码 Excel 不会冻结且 CPU 使用率低:

    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
    

    【讨论】:

      【解决方案7】:

      以下是与 32 位和 64 位 Windows 计算机交叉兼容所需的条件。延迟以毫秒为单位,因此使用 1000 表示 1 秒延迟。

      首先,将它放在模块中的其他子/函数之上。在 64 位计算机上,“#Else”之后的行将突出显示,就好像有错误一样,但这不是问题。代码将编译并运行。

      #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
      

      现在你可以像这个例子一样创建一个延迟 1.5 秒的延迟:

      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
      

      正如@SLaks 所述,这会冻结应用程序(阻止用户输入),但您也可以在While 循环中调用DoEvents。请参见下面的示例。它运行 10 秒并允许用户交互。

      每隔 1/10 秒,它会更新 Excel 状态栏:

      1. 活动单元格的地址

      2. 倒计时

        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
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 2019-01-21
        • 2017-07-16
        • 2018-02-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多