FC2ブログ

スポンサーサイト 


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--/--/--

Category: スポンサー広告

TB: --  /  CM: --

top △

タイマ時の動き 


タイマ時は、ある一定間隔で処理したい等・・・便利で使います。
過去記事「遊んでみますか の2」でもやってます。
また、今のタイミングではなく、チョッと後で処理したい・・・こういった時に使いますね。

使っていて、疑問になるのが・・・・
一定間隔以上にタイマ時内の処理がかかる様な事があったら・・・どの様な動きになるのだろうか
つまり、間隔(TimerInterval)を 1000 (1秒)に設定した際、
タイマ時内の処理が2秒・3秒~~に、なってしまったら・・・・
設定した間隔通り、処理が始まってしまうのだろうか・・・・

待たされるような気がするんだけど・・・・
確認してみればわかる事なので、以下のフォームを作って確認してみる事に・・・

kEnt162_F2  kEnt162

用意した確認用フォームは「F2」「F2A」「F2B」「F2C」の4つ。
画面構成は、「F2A」「F2B」「F2C」は同じなので、2種類。
 
確認の方針)タイマ時の処理内で Sleep してみる。

TimerInterval を指定するテキストボックス「txt1」
Sleep の ms を指定するテキストボックス「txt2」
タイマ時が呼ばれた時のカウントアップ用にテキストボックス「txt3」

を配置して、確認「開始」用のコマンドボタン「btn1」
状況表示用のラベル「lab1」

これらを配置します。

kEnt162_F2

フォーム「F2」

このフォームでは、1回の Sleep で時間を稼いでみます。
初期では
・TimerInterval=1000 / Sleep (ms) = 500 となっているので、このまま実行すると
タイマ時は1秒間隔で呼び出されます。
その処理内で 500 ms Sleep で待つ・・・・・

このまま実行すると、確かに1秒間隔でタイマ時が呼ばれる事を確認できます。
そこで、Sleep (ms) = 5000 (5秒)として実行してみると・・・・
1秒間隔でカウントアップされていた数値は、5秒間隔程度に・・・・
・・・・ということは、タイマ時実行中は、再度タイマ時が実行はされない???

あっ、そうそう 確認用に記述したVBAは以下になります。
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Form_Timer()
  Me.lab1.Caption = "Timer In : " & Timer
  Me.Repaint
  Me.txt3 = Nz(Me.txt3) + 1
  Me.lab1.Caption = "Sleep In : " & Timer
  Me.btn1.Enabled = False
  Me.Repaint
  Sleep Nz(Me.txt2, 500)
  Me.lab1.Caption = "Sleep Out : " & Timer
  Me.btn1.Enabled = True
  Me.Repaint
End Sub

Private Sub Form_Load()
  Me.txt1 = 1000
  Me.txt2 = 500
  Me.txt3 = 0
  Me.lab1.Caption = ""
  Me.btn1.Caption = "開始"
End Sub

Private Sub btn1_Click()
  If (Me.btn1.Caption = "開始") Then
    Me.lab1.Caption = ""
    Me.btn1.Caption = "停止"
    Me.TimerInterval = Nz(Me.txt1, 1000)
    Me.txt3.SetFocus
  Else
    Me.TimerInterval = 0
    Me.btn1.Caption = "開始"
  End If
End Sub

 
「Sleep (ms)」= 5000 とかにして動きを見てみると、次のタイマ時は呼ばれないですね。


フォーム「F2A」

確認の方法が悪いのかも・・・・・ということで、
Sleep の処理を変更してみます。

Sleep は1回ではなく、100 ms を指定した ms 分ループする様に・・・
で、このループ中に DoEvents を発行するかどうか・・・・
フォーム「F2」を「F2A」名でコピーし、DoEvents 指定用のチェックボックス「cb1」を追加します。

kEnt162

確認用に記述したのは以下になります。
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Form_Timer()
  Dim i As Long

  Me.lab1.Caption = "Timer In : " & Timer
  Me.Repaint
  Me.txt3 = Nz(Me.txt3) + 1
  Me.lab1.Caption = "Sleep In : " & Timer
  Me.btn1.Enabled = False
  Me.Repaint
  For i = 1 To Nz(Me.txt2, 500) ¥ 100
    Sleep 100
    If (Me.cb1) Then DoEvents
  Next

  Me.lab1.Caption = "Sleep Out : " & Timer
  Me.btn1.Enabled = True
  Me.Repaint
End Sub

Private Sub Form_Load()
  Me.txt1 = 1000
  Me.txt2 = 500
  Me.txt3 = 0
  Me.lab1.Caption = ""
  Me.btn1.Caption = "開始"
  Me.cb1 = False
End Sub

Private Sub btn1_Click()
  If (Me.btn1.Caption = "開始") Then
    Me.lab1.Caption = ""
    Me.btn1.Caption = "停止"
    Me.TimerInterval = Nz(Me.txt1, 1000)
    Me.txt3.SetFocus
  Else
    Me.TimerInterval = 0
    Me.btn1.Caption = "開始"
  End If
End Sub

 
「Sleep (ms)」= 5000 とかにして動きを見てみると、
DoEvents が有ろうが無かろうが、次のタイマ時は呼ばれないですね。


フォーム「F2B」

これの確認はあまり意味はないのですが・・・
タイマ時先頭で Me.TimerInterval = 0 して、戻る直前に再度 Me.TimerInterval を設定する様に

フォーム「F2A」を「F2B」名でコピー後、以下部分を変更します。
Private Sub Form_Timer()
  Dim i As Long

  Me.TimerInterval = 0
  Me.lab1.Caption = "Timer In : " & Timer
  Me.Repaint
  Me.txt3 = Nz(Me.txt3) + 1
  Me.lab1.Caption = "Sleep In : " & Timer
  Me.btn1.Enabled = False
  Me.Repaint
  For i = 1 To Nz(Me.txt2, 500) ¥ 100
    Sleep 100
    If (Me.cb1) Then DoEvents
  Next
  Me.lab1.Caption = "Sleep Out : " & Timer
  Me.btn1.Enabled = True
  Me.Repaint
  Me.TimerInterval = Nz(Me.txt1, 1000)
End Sub

 
「Sleep (ms)」= 5000 とかにして動きを見てみると、
DoEvents が有ろうが無かろうが、次のタイマ時は呼ばれないですね。
(この記述では当然の様な気がします)


フォーム「F2C」

じゃ、チョッと思考を変えて・・・・
タイマ時では単にカウントアップするだけ
ボタンを押した時の処理で Sleep してみる。

フォーム上の構成は同じなので「F2B」を「F2C」名でコピー後、以下記述に全面変更
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Form_Timer()
  Me.txt3 = Nz(Me.txt3) + 1
End Sub

Private Sub Form_Load()
  Me.txt1 = 500
  Me.txt2 = 1000
  Me.txt3 = 0
  Me.lab1.Caption = ""
  Me.btn1.Caption = "開始"
  Me.cb1 = False
  Call txt1_AfterUpdate
End Sub

Private Sub txt1_AfterUpdate()
  Me.TimerInterval = Nz(Me.txt1, 500)
  Me.lab1.Caption = "TimerInterval = " & Nz(Me.txt1, 500) & " Set"
End Sub

Private Sub btn1_Click()
  Dim i As Long

  Me.lab1.Caption = "Sleep In : " & Timer
  Me.Repaint
  For i = 1 To Nz(Me.txt2, 1000) ¥ 100
    Sleep 100
    If (Me.cb1) Then DoEvents
  Next
  Me.lab1.Caption = ""
  Me.Repaint
End Sub

 
フォームを起動すると、タイマ時が動きカウントアップが始まります。
「Sleep (ms)」= 5000 とかにして動きを見てみると、DoEvents しないと、タイマ時は動きませんね。


※※
これらのフォームで、「Sleep (ms)」>「TimerInterval」として確認していると
終了することが困難な場合があります。特にフォーム「F2」「F2A」


その時には、フォーム右上の「×」で閉じてください。
マウスでチョコチョコ・・・チョコチョコ・・・チョコチョコ・・・クリックしていると閉じれるかと・・・・
その際に以下エラーになる事がありますが問題ないでしょう・・・

実行時エラー '2467'
指定した式で、閉じているかまたは存在しないオブジェクトを参照しています。



これらの動きを見てみると、
タイマ時の処理に時間がかかっても、一定間隔で実行される事はなく、
タイマ時処理が終わるのを待つ・・・・

という結論になるのでしょうか・・・


確認の仕方が悪い・・・・等、教えてください。

サンプルは以下
 バージョン 20002003 (2002)2007
 ファイル kEnt162_2000.zipkEnt162_2003.zipkEnt162_2007.zip
 サイズ 22,49224,08825,506
※ ファイルは zip 形式
※ 2007 以外は、2007 保存時に変換 & 各バージョンで動作確認 & 最適化

関連記事

2013/05/26

Category: やってみる

TB: --  /  CM: 2

top △

この記事に対するコメント

#mQop/nM. | URL | 2013/05/27 21:17 * edit *

情報ありがとうございます

同じ結果という事で、間違った確認方法ではなかった・・・・かと

疑問・不安が出たら、やってみる・・・にしているので・・・
検索がうまくなればなぁ・・・と、常々思っております
検索してからでも、やっぱり自分でやってみるのかなぁ・・・・

今回の確認での収穫は、フォーム「F2C」での動きでしょうか・・・
何かに使えそうな気がします

kiku #1a/xiM.Q | URL | 2013/05/28 03:24 * edit *

top △

コメントの投稿

Secret

top △


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。