1. 程式人生 > 其它 >VBA: 因為1個簡單時間clock引發得一連串問題, application.ontime 不會自迴圈,而 call 自身或者 go label則會真的自迴圈。

VBA: 因為1個簡單時間clock引發得一連串問題, application.ontime 不會自迴圈,而 call 自身或者 go label則會真的自迴圈。

技術標籤:VBA

application.ontime

application.ontime 比 application.wait要好,不會一直佔用程序。

1 網上看到一個寫簡單自動計時的例子

  • 確實可以迴圈執行
  • 但是壞處是,會一直迴圈執行
  • 但是application.ontime 比 application.wait要好,不會一直佔用程序。
Sub clock0()
    Range("a1").Value = Time()
    testcount0
End Sub



Sub testcount0()
   Application.OnTime Now() + TimeValue("00:00:01"), procedure:="clock0"
End Sub

2自己改寫了一個,自己呼叫自己,也可以迴圈執行,同網上例子效果

Sub clock3()
    Range("a1").Value = Time()
    Application.OnTime Now() + TimeValue("00:00:01"), procedure:="clock3"
End Sub

用go1 應該也能實現

3 但是馬上就想到,要執行有限次怎麼修改

  • 達到了有限次計次的效果
  • 為什麼不用application.ontime ,因為做不到迴圈執行
  • application.ontime 好像只會執行一次
  • 我是用application.wait 達到類似的效果,但wait會卡住佔住程序,執行時幹不了別的
Sub testcount2()
    count1 = 0
    Do Until count1 >= 10
        Application.Wait Now() + TimeValue("00:00:01")
        Range("a1").Value = Time()
        count1 = count1 + 1
        Range("b1").Value = count1
        Debug.Print "count=" & count1
    Loop
End Sub

4 測試用application.ontime 迴圈呼叫計時,但是不好使

  • application.ontime 相當於多執行緒?

  • application.ontime 相當於開啟了一個計劃外任務,且定時的

  • application.ontime 感覺會等其他程式執行完了,才會開始執行,而且在本例子裡不會迴圈。


Sub clock1()
    Range("a1").Value = Time()
End Sub



Sub testcount1()
i = 0
For i = 1 To 10    '迴圈不加處理,則會瞬間執行完成,不會等待

   Range("b1") = i
   Application.Wait Now() + TimeValue("00:00:01")  'wait會佔住程序,幹不了其他事情,ontime最靈活
   Application.OnTime Now() + TimeValue("00:00:00"), procedure:="clock1"   '即使TimeValue("00:00:00")也迴圈完成後只執行1次,?
   Debug.Print i
Next


End Sub

5 即使在一個函式裡用application.ontime重複呼叫自己,其實一次只會執行1次,並不會像 call 自身函式名 或 go label 這樣,會迴圈執行自己

  • 函式內,自己呼叫自己,會迴圈執行(可以提前寫跳出條件),用 call 自身 或 自身就可以
  • go label 也可以
  • 但是 application.ontime 寫著看起來像自迴圈,但實際上並不會

Public count

Sub clock7()
    If count <= 3 Then
        Debug.Print count
        Debug.Print "clock1執行"
'        Call clock7  '錯誤,必須在count=count+2 之後,否則呼叫時機不對,會死迴圈

        Range("a1").Value = Time()
        Debug.Print "clock2執行"
        count = count + 2
'        Call clock7   '或者用 go  1 ?
        Debug.Print "clock3執行"
        Application.OnTime Now() + TimeValue("00:00:01"), procedure:="clock7"  '事實證明,這個Application.OnTime不會重複執行,只會呼叫自己1次
        Debug.Print "clock4執行"

    End If
End Sub

Sub count7()
    count = 0
    Call clock7
    Do While count <= 5
       Application.Wait Now() + TimeValue("00:00:01")
       count = count + 1
       Range("b1").Value = count
       Debug.Print count
       Debug.Print "count執行"
    Loop

End Sub

這樣測試也是

  • for 迴圈時瞬時計算,不停的。
  • 想要間隔時間,就要加類似的 application.wait等
  • 另外 clock6()裡寫了application.ontime clock6 其實只會執行1次,並不會迴圈。而用call clock6 則會迴圈,可測試
  • 呼叫count6()試一下就知道
Public count

Sub clock6()
    If count <= 3 Then
        Debug.Print count
        Debug.Print "clock執行"
'        Range("a1").Value = Time()
        Application.OnTime Now() + TimeValue("00:00:01"), procedure:="clock6"
        count = count + 2
'        Call clock6

    End If
End Sub

Sub count6()
    count = 0
    Call clock6
    Do While count <= 5
       Application.Wait Now() + TimeValue("00:00:01")
       count = count + 1
       Range("b1").Value = count
       Debug.Print count
       Debug.Print "count執行"
    Loop

End Sub

如果用call 會真自迴圈

  • 記得要用 公共變數 public 或者private 傳遞變數資料到不同的sub
  • 執行count5 可以發現, clock5 時瞬時完成的,但是count5內是逐秒執行的
Public count

Sub clock5()
    If count <= 5 Then
        Debug.Print count
        Debug.Print "clock執行"
'        Range("a1").Value = Time()
'        Application.OnTime Now() + TimeValue("00:00:01"), procedure:="clock4"
        count = count + 2
        Call clock5

    End If
End Sub

Sub count5()
    count = 0
    Call clock5
    Do While count <= 10
       Application.Wait Now() + TimeValue("00:00:01")
       count = count + 1
       Range("b1").Value = count
       Debug.Print count
       Debug.Print "count執行"
    Loop

End Sub