VBA睡眠不';行不通

VBA睡眠不';行不通,vba,sleep,Vba,Sleep,我知道我做错了什么。我试图使用sleep函数来延迟我的代码,但我得到了“Sub或function not defined”错误。有什么提示吗?VBA没有睡眠功能 您可以像这样从Kernel32.dll导入它: Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 请注意,这将冻结应用程序。 您还可以在While循环中调用DoEvents,这不会冻结应用程序。您还可以暂停当前宏上下文,这不会阻止整个过程。我尝试的所有操作似

我知道我做错了什么。我试图使用sleep函数来延迟我的代码,但我得到了“Sub或function not defined”错误。有什么提示吗?

VBA没有睡眠功能

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

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
请注意,这将冻结应用程序。

您还可以在
While
循环中调用
DoEvents
,这不会冻结应用程序。

您还可以暂停当前宏上下文,这不会阻止整个过程。

我尝试的所有操作似乎都会挂起应用程序,包括application.Wait。但这似乎是可行的:

waitTill = Now() + TimeValue("00:15:00")

While Now() < waitTill
    DoEvents
Wend
waitTill=Now()+TimeValue(“00:15:00”)
而现在()
使用此代码,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
声明子睡眠库“kernel32”(ByVal-dwms长度)
子延迟(作为单个)
将超时设置为单个
超时=计时器+s
计时器<超时时执行此操作
多芬特
睡眠1’这一行的CPU使用率是00而不是50,绝对误差为+1ms,延迟为1ms。
环
端接头
暂停应用程序10秒。


以下是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状态栏:

  • 活动单元格的地址

  • 倒计时

    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
    

  • 我应该把声明放在代码的什么地方?我试着把它放在我正在工作的sub的内部和外部,但是两次都出现了错误。哦,糟糕,我试着把它放进一个excel对象(愚蠢的我)。我把它放在一个模块中,现在它可以工作了。非常感谢!我检查了你的答案。尽管存在挂起应用程序的问题,但我还是喜欢这种方法,因为循环方法占用了太多的CPU。@kalengi:你应该使用异步。@SLaks async with Sleep,或者你的意思是什么?欢迎使用堆栈溢出!谢谢你的回复!请务必仔细阅读本手册。还要注意的是,每次链接到自己的网站/产品时,都必须发布免责声明。@AndrewBarber:看一下链接,它看起来不像Babu的网站,而更像是SO的有用读物。你为什么要删除它?@PeterAlbert这是Babu的网站。他们最近发了很多垃圾邮件(他们的多个答案被当作垃圾邮件删除,因为他们甚至没有包含这么多的信息),并且在他们的个人资料中。@AndrewBarber-谢谢你的信息!我得承认,我不会注意到的!“m”=月份;如果你想要几分钟,用“n”我喜欢这个,它工作得很好。。只有一个例外。我找不到做500毫秒的方法。。。所以1秒是最短的等待时间。有没有一种方法可以在不到1秒的时间内完成?如果需要更高的分辨率,可以在kernel32.dll中使用GetSystemTime:或者,如果在Excel中,可以调用电子表格now()函数(作为VBA中的[now()])它还具有更高的分辨率:在Excel中,您可以使用方括号括起对Now的调用,以获得精度低于秒的工作表函数版本
    [Now()]
    一个更优雅的解决方案:)这只适用于
    Excel.Application
    Wait
    方法不适用于其他Office应用程序对象模型。您好,您有什么理由认为此功能在MS Outlook中不可用?由于某些原因,Alt+F11 VBA编辑器似乎没有显示它,并且当我在Outlook邮件的函数中运行它时(根据规则),它将不起作用。谢谢
    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
    
    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