我目前正在使用PowerPoint演示文稿,该演示文稿正在计算机上用作某种信息亭或信息屏幕。它从磁盘上的文本文件中读取文本。此文本文件中的文本显示在PowerPoint的文本框中,每5秒钟进行一次刷新。这样,我们可以在PowerPoint中编辑文本而无需编辑PowerPoint演示文稿本身,以便它继续运行。到目前为止,工作得很好,只有PowerPoint VBA不包含应用程序。等待功能。请参阅此处的完整子:
Sub Update_textBox_Inhoud()
Dim FileName As String
TextFileName = "C:pahttotextfile.txt"
If Dir$(FileName) <> "" Then
Application.Presentations(1).SlideShowSettings.Run
Application.WindowState = ppWindowMinimized
While True
Dim strFilename As String: strFilename = TextFileName
Dim strFileContent As String
Dim iFile As Integer: iFile = FreeFile
Open strFilename For Input As #iFile
strFileContent = Input(LOF(iFile), iFile)
Application.Presentations(1).Slides(1).Shapes.Range(Array("textBox_Inhoud")).TextFrame.TextRange = strFileContent
Close #iFile
waitTime = 5
Start = Timer
While Timer < Start + waitTime
DoEvents
Wend
Wend
Else
End If
End Sub
您可以看到,我在循环中有一个循环来创建5秒的睡眠/等待功能,因为PowerPoint没有应用程序。等待功能。
在运行此宏时,我的第7代i5上的CPU负载可达36%。售货亭计算机的硬件稍差,因此CPU负载将很高,并且该PC的粉丝会发出很多噪音。
我认为睡眠/等待功能并不是真正"睡眠",它一直持续到5秒之前。
问题1:我的假设是该功能并不是真正的睡眠吗?问题2:如果问题1的答案是真的,是否有更好,更少的CPU密集方法来创建睡眠功能?
等待特定的时间,请致电WaitMessage
,然后在循环中进行DoEvents
。它不是CPU密集型,UI将保持响应:
Private Declare PtrSafe Function WaitMessage Lib "user32" () As Long
Public Sub Wait(Seconds As Double)
Dim endtime As Double
endtime = DateTime.Timer + Seconds
Do
WaitMessage
DoEvents
Loop While DateTime.Timer < endtime
End Sub
这是我的终极睡眠过程,共同包含所有好处:
- &lt; 0.0%CPU
- doevents
- 准确性 - &lt; 10ms
Public Sub Sleep(ms As Currency)
Dim cTimeStart As Currency, cTimeEnd As Currency
Dim dTimeElapsed As Currency, cTimeTarget As Currency
Dim cApproxDelay As Currency
getTime cTimeStart
Static cPerSecond As Currency
If cPerSecond = 0 Then getFrequency cPerSecond
cTimeTarget = ms * (cPerSecond / 1000)
If ms <= 25 Then
'empty loop for improved accuracy (SleepAPI alone costs 2-15ms and DoEvents 2-8ms)
Do
getTime cTimeEnd
Loop Until cTimeEnd - cTimeStart >= cTimeTarget
Exit Sub
Else 'fully featured loop
SleepAPI 5 '"WaitMessage" avoided because it costs 0.0* to 2**(!) ms
DoEvents
getTime cTimeEnd
cApproxDelay = (cTimeEnd - cTimeStart) / 2
cTimeTarget = cTimeTarget - cApproxDelay
Do While (cTimeEnd - cTimeStart) < cTimeTarget
SleepAPI 1
DoEvents
getTime cTimeEnd
Loop
End If
End Sub
Sleep
不需要CPU周期。
Sleep
是Windows功能,而不是VBA函数,但是您仍然可以通过调用Windows Sleep
API在VBA代码中使用此功能。实际上sleep
是Windows DLL文件中存在的功能。因此,在使用它们之前,您必须在模块中的代码上方声明API的名称。
Sleep
语句的语法如下:
Sleep (delay)
示例:
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long) 'For 32 Bit Systems
#End If
Sub SleepTest()
MsgBox "Execution is started"
Sleep 10000 'delay in milliseconds
MsgBox "Execution Resumed"
End Sub
基本上您的代码将如下:
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
#End If
Sub Update_textBox_Inhoud()
Dim FileName As String
TextFileName = "C:pahttotextfile.txt"
If Dir$(FileName) <> "" Then
Application.Presentations(1).SlideShowSettings.Run
Application.WindowState = ppWindowMinimized
While True
Dim strFilename As String: strFilename = TextFileName
Dim strFileContent As String
Dim iFile As Integer: iFile = FreeFile
Open strFilename For Input As #iFile
strFileContent = Input(LOF(iFile), iFile)
Application.Presentations(1).Slides(1).Shapes.Range(Array("textBox_Inhoud")).TextFrame.TextRange = strFileContent
Close #iFile
Sleep 5000
Wend
Else
End If
End Sub
结论:您没有使用真实的sleep
函数。您正在做的是使用 CPU 循环..
请注意,此答案中的几个信息已在此网站上找到: -> source
尝试以下
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
#End If
Sub Update_textBox_Inhoud()
Dim FileName As String
TextFileName = "C:pahttotextfile.txt"
If Dir$(FileName) <> "" Then
Application.Presentations(1).SlideShowSettings.Run
Application.WindowState = ppWindowMinimized
While True
Dim strFilename As String: strFilename = TextFileName
Dim strFileContent As String
Dim iFile As Integer: iFile = FreeFile
Open strFilename For Input As #iFile
strFileContent = Input(LOF(iFile), iFile)
Application.Presentations(1).Slides(1).Shapes.Range(Array("textBox_Inhoud")).TextFrame.TextRange = strFileContent
Close #iFile
Sleep 5000
Wend
Else
'Is there no code here?
End If
End Sub
它使用Sleep
API函数,该功能基于Windows,因此不限于Excel。
睡眠使用毫秒中的值,因此在这种情况下,您需要5000
编辑
#If VBA7 Then
Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal _
lpTimerFunc As Long) As Long
Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
#Else
Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal _
lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
#End If
Dim lngTimerID As Long
Dim blnTimer As Boolean
Sub StartOnTime()
If blnTimer Then
lngTimerID = KillTimer(0, lngTimerID)
If lngTimerID = 0 Then
MsgBox "Error : Timer Not Stopped"
Exit Sub
End If
blnTimer = False
Else
lngTimerID = SetTimer(0, 0, 5000, AddressOf Update_textBox_Inhoud)
If lngTimerID = 0 Then
MsgBox "Error : Timer Not Generated "
Exit Sub
End If
blnTimer = True
End If
End Sub
Sub KillOnTime()
lngTimerID = KillTimer(0, lngTimerID)
blnTimer = False
End Sub
Sub Update_textBox_Inhoud()
Dim FileName As String
TextFileName = "C:pahttotextfile.txt"
If Dir$(FileName) <> "" Then
Application.Presentations(1).SlideShowSettings.Run
Application.WindowState = ppWindowMinimized
Dim strFilename As String: strFilename = TextFileName
Dim strFileContent As String
Dim iFile As Integer: iFile = FreeFile
Open strFilename For Input As #iFile
strFileContent = Input(LOF(iFile), iFile)
Application.Presentations(1).Slides(1).Shapes.Range(Array("textBox_Inhoud")).TextFrame.TextRange = strFileContent
Close #iFile
Else
'Is there no code here?
End If
End Sub
根据此线程