我正在尝试在sub中使用多个Application.OnTime,我得到了意想不到的结果。
这就是我想要做的事情:
使用"递归"每隔1分钟运行一个sub(testOnTime)调用
内部子(testOnTime):
run" firstSection"进入sub(testOnTime)后10秒
Inside" firstSection":将调试消息写入Excel工作表" MySheet"
run" lastSection"进入sub(testOnTime)后40秒
Inside" lastSection":将调试消息写入Excel工作表" MySheet"
将调试信息写入Excel工作表" Mysheet"
有sub" testOnTime"跑5次?:不 - >继续,是 - >出口
代码:
Option Explicit
Public rowCnt As Integer
Public Cnt As Integer
Public Const sheetName = "MySheet"
Public Const inc1 = "00:00:40"
Public Const inc2 = "00:00:10"
Public timeStr1 As Date
Public timeStr2 As Date
Public timeStr3 As Date
Public Sub MyMain()
rowCnt = 1
Cnt = 0
Call testOnTime
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "Done"
End Sub
Public Sub testOnTime()
' wait-time for last section
timeStr1 = Format(Now + TimeValue(inc1), "hh:mm:ss")
' wait time for first section
timeStr2 = Format(Now + TimeValue(inc2), "hh:mm:ss")
' wait for 1 minute
timeStr3 = Format(Now + TimeValue("00:01:00"), "hh:mm:ss")
' wait utill 10 seconds
Application.OnTime TimeValue(timeStr2), "firstSection"
' wait utill 40 seconds
Application.OnTime TimeValue(timeStr1), "lastSection"
' debug msgs
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "Outside @ " & CStr(timeStr3)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
Cnt = Cnt + 1
If Cnt < 5 Then
' wait until Now + 1 min
Application.OnTime TimeValue(timeStr3), "testOnTime"
End If
End Sub
Public Sub firstSection()
' debug msgs for first section
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "In first section @ " & CStr(timeStr2)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
End Sub
Public Sub lastSection()
' debug msgs for first section
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "In last section @ " & CStr(timeStr1)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
End Sub
为什么&#34;外面......&#34;首先写入excel表,当它应该是宏内的最后一条指令时?
为什么宏输出&#34; 2&#34;应该只输出一次的同一件事的消息?
有没有更好的方法来实现我想要的目标而不使用&#34; OnTime&#34;?
答案 0 :(得分:2)
我运行了代码,我觉得它运行正常 - 我必须承认我对它的目标有点困惑。我没有看到任何加倍的消息。
我能够通过运行两次宏来设计加倍的消息 - excel很高兴让它运行两次,然后你会得到一倍的消息。这是什么导致了这个问题?
我认为你误解了Application.OnTime是如何运行的 - 它是一个非阻塞调用,因此它创建了对指定子例程的未来调用,然后继续 - 这就是&#34; outside&#34;消息首先显示。我认为这也是&#34; Done&#34;消息会立即显示,直到它被覆盖。
希望这有帮助
答案 1 :(得分:0)
我认为我找到了实现我想要实现的目标的方法,下面是代码
更新代码:
Option Explicit
Public rowCnt As Integer
Public Cnt As Integer
Public Const sheetName = "MySheet"
Public Const inc1 = "00:00:40"
Public Const inc2 = "00:00:10"
Public timeStr1 As Date
Public timeStr2 As Date
Public timeStr3 As Date
Public firstFlag As Boolean
Public lastFlag As Boolean
Public Sub MyMain()
rowCnt = 1
Cnt = 0
Call testOnTime
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "Done"
End Sub
Public Sub testOnTime()
' wait-time for last section
timeStr1 = Format(Now + TimeValue(inc1), "hh:mm:ss")
' wait time for first section
timeStr2 = Format(Now + TimeValue(inc2), "hh:mm:ss")
' wait for 1 minute
timeStr3 = Format(Now + TimeValue("00:01:00"), "hh:mm:ss")
' wait utill 10 seconds
firstFlag = False
Application.OnTime TimeValue(timeStr2), "firstSection"
While Not firstFlag
DoEvents
Wend
' wait utill 40 seconds
lastFlag = False
Application.OnTime TimeValue(timeStr1), "lastSection"
While Not lastFlag
DoEvents
Wend
' debug msgs
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "Outside @ " & CStr(timeStr3)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
Cnt = Cnt + 1
If Cnt < 5 Then
' wait until Now + 30 seconds
Application.OnTime TimeValue(timeStr3), "testOnTime"
End If
End Sub
Public Sub firstSection()
' debug msgs for first section
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "In first section @ " & CStr(timeStr2)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
firstFlag = True
End Sub
Public Sub lastSection()
' debug msgs for first section
Worksheets(sheetName).Range("A" & CStr(rowCnt)).Value = "In last section @ " & CStr(timeStr1)
Worksheets(sheetName).Range("B" & CStr(rowCnt)).Value = CStr(rowCnt)
Worksheets(sheetName).Range("C" & CStr(rowCnt)).Value = CStr(Cnt)
rowCnt = rowCnt + 1
lastFlag = True
End Sub
因此,我为每个部分实例化一个标志,该标志设置为FALSE,在宏内部,该标志将设置为TRUE。在Application.OnTime之后,我检查TRUE标志,如果不是,我等待(使用DoEvents)。这确保了在执行非阻塞OnTime之后,程序等待&#34;直到该特定宏已经执行,然后继续。这应该符合我的目的。