お世話になります。
環境はVB6.0です。
チェックボックスを配列していで複数使用しております。
1つのチェックボックスを選択するごとに 処理を行うのですが
処理中に 他のチェックボックスを選択すると
前の処理終了後に 処理中に押されたチェックボックスの
処理が起動してしまうのですが
チェックボックスの処理が終わるまで 他のチェックボックスを認識
しないようにするためにはどうすればよろしいでしょうか?
よろしくお願いいたします。
チェックボックスのチェックで走る処理は時間のかかる処理なのですか?
また、その処理中でDoEventsを使っていませんか?
DoEventsがあると、その時点でキューに溜まっていたメッセージが
処理されてしまいますので、もし問題が無ければDoEventsを消してください。
追記:
チェックボックスのClickイベントの最初で
全チェックボックスのEnabledをFalseにして、
イベントを抜ける直前で全チェックボックスのEnabledをTrueにする
という方法もあります。
見た目的にあまり宜しくありませんが。
処理中かどうかを判定するフラグを一つ用意して、
Clickイベントの最初にそれを判定するようにするのが
一番すっきりするかと思います。
チェックボックスはValueプロパティを変更することが
Clickイベントの発生要因になりますので、その点も注意して
プログラムを見直しましょう。
皆様 ありがとうございました。
処理中でDoEventsは使用していなかったので
処理前に判定するフラグを一つ用意して、
Clickイベントの最初にそれを判定するようにするようにしたのですが
やはり処理が走ってしまいました。。
一応 他に対策として
処理前に自フォームをEnabledをFalseにして
処理終了後にTrueにするなど いろいろ試したのですが・・
まだ 回避できておりません。
申し訳ございませんが もう少し皆様からのご意見をお聞かせ願えれば
幸いです。。宜しくお願い致します。。。
フラグでどのように判定しようとしていたのですか?
こんな感じでうまくいくと思いますが。
Private Sub Check1_Click(Index As Integer)
Static flgCheck As Boolean
If flgCheck Then Exit Sub
flgCheck = True
処理
flgCheck = False
End Sub
> 処理前に判定するフラグを一つ用意して、
> Clickイベントの最初にそれを判定するようにするようにしたのですが
> やはり処理が走ってしまいました。。
フラグで回避する方法はイベント自体を回避するのではなく、
イベントが発生した時に必ず処理が走ってしまうのを防ぐための方法です。
なので、LESIAさんのレスのようにプロシージャの頭でExit Subしてやれば、
処理は走らないはずですが。
ただし、処理は走らないもののチェックは入ってしまうので、
それを元に戻さないといけないでしょう。とすると、
ひろさんのレスにあるように、またClickイベントが走ることに・・・
タイミングによってはおかしな動きをするかもしれません。
確率的にはもの凄く低い確立になるでしょうが。
やはりEnabledのTrue,Falseを切り替えるのが一番いいような気もします。
Clickイベントの中での処理は具体的にはどのようなことを
しているのですか?
あ、そういえば処理は走らないですけど、チェックは入ってしまいますね。
聖 羅樹さん、ありがとうございます。
あこさんの言っている、処理が走るというのはチェックが入ってしまう事
なのかも。
Private Sub Check1_Click(Index As Integer)
Dim i As Integer
For i = Check1.LBound To Check1.UBound
Check1(i).Enabled = False
Next i
処理
DoEvents
For i = Check1.LBound To Check1.UBound
Check1(i).Enabled = True
Next i
End Sub
皆様 ありがとうございます。
>Clickイベントの中での処理は具体的にはどのようなことを
しているのですか?
具体的な処理は メッセージ関数を発行し
その判定内容により エクセル表を作成し印刷する処理が
入っております。
エクセル表は表示せずに裏で動いています。
今は環境がないので すぐに上記の処理を
ためしてみることはできませんが
明日 上記の方法でこころみてみます(^-^)
こんにちは。
下記のコードで試してみたのですが・・
チェックされていた処理が終了すると 次のチェックされた処理が
走ってしいまいました。
・・フォームを触れないようにしたりしても チェックはされているのですが
下記の方法以外で なにかいい方法ありましたら
またよろしくお願いいたします。
Private chkbox_flg as Integer 'フラグ(フォーム内のグローバル)
Private Sub chk_box_Click(Index As Integer)
Dim i As Integer
Dim i_response As Integer
If chkbox_flg = 1 Then Exit Sub
form1.Enabled = False
pi_index = 0
If chk_box(Index).Value = vbChecked And chkbox_flg = 0 Then
chkbox_flg = 1
pi_index = Index '選択リスト設定
i_response = MsgBox("確認", vbYesNoCancel, "印刷しますか?")
Select Case i_response
Case vbYes, vbNo
'印刷処理を行う
'EXCEL出力処理
Case Else
End Select
End If
'チェックボックスの初期化
For i = chk_box.LBound To chk_box.UBound
chk_box(i).Value = vbUnchecked
Next i
form1.Enabled = True '自画面の使用可
form1.SetFocus
End Sub
あこさん、はまりましたね(^^;
チェックボックスは結構いやらしいんです。
基本的にはこれでいいはずです。
Private Sub chk_box_Click(Index As Integer)
Static flg As Boolean
If flg = True Then
chk_box(Index) = vbUnchecked
Exit Sub
End If
flg = True
If MsgBox("確認", vbYesNo, "処理をしますか?") = vbYes Then
Select Case Index
Case 0 To 4
'印刷処理
Case 2
'何かの処理
Case 3
'.....
End Select
End If
chk_box(Index).Value = vbUnchecked
flg = False
End Sub
ねろさま ありがとうございました。
上記のとおり 試してみました。
ブレイクポイントを設定して実行するとうまくチェック判定されるのですが・・
ブレイクポイントをはずすと 次のチェック処理が走ってしまいました。
ブレイクポイントを設定するしない実行処理が違うことなど
あるのでしょうか?
ブレークポイントはどこに設定しているのでしょうか?
> If flg = True Then
> chk_box(Index) = vbUnchecked
> Exit Sub
> End If
こちらのほうにチェックしました。
ちょっとした推理物ですね。
処理させているのは、印刷とかEXCELへの出力処理ですか。
これらの処理に忙しくて、Windowsはチェックボックスのチェックを
入れる等の時間のかかるメッセージをVBの方にまわす事が出来ず、
キューを溜め込み、印刷やEXCELへの出力処理が終わった時に、
ようやくchk_box_Click処理を行う、しかしその時は
実際にチェックボックスにチェックを書き込むGUIの処理より
軽い、chk_box_Click内の印刷などの後処理のflgを戻す処理を
先に済ませてしまうので、flgはFalseにリセットされて、
次のチェックの処理をしてしまう。
ブレークをかけると、現在のスレッドは止まってしまうが、
印刷やEXCELの出力は非同期に終了して、ブレークを解除した時は
スレッドの処理はflg=Trueの中から始まるので、次の処理には落ちない。
こんなことが起こっているのかな。
次の関数をchk_box_Clickのおしまいにいれて、少し時間を稼いだら
どうだろうか。
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Dim t As Long
t = timeGetTime
Do
DoEvents
Loop While (timeGetTime - t < 20)
> ブレイクポイントを設定するしない実行処理が違うことなど
> あるのでしょうか?
結論から言えばあります。
私もねろさんのレスにあるような状況になっているのではないかと
思うのですが、ブレークポイントではなく、
Debug.Print を使って、実際どのように処理が流れているのかを
調べてみてはいかがでしょうか。
その際、フラグの状態も書き出すようにしてみては。
私はステップ実行 or ブレークポイント設定時と
実行時の動きが違う場合は、Debug.Printを使って調べています。
もしかしたら、なぜフラグチェックをすり抜けてしまうのか
分かるかもしれません。
よく考えてみましたら、当たり前のことを見逃していましたので、追記。
2つのチェックボックスがあって、①をチェックして、
処理中に②をチェックした場合の動きを書きますと、
(コードはねろさんのを参考にしています)
1.①のClickイベントが走り、フラグがTrueになる
2.処理中に②のチェックボックスをクリック(画面上は変化なし)
3.①の処理が終わり、自身のチェックを外す(Value = vbUnchecked)
4.①のClickイベントが再度走る。但し、フラグチェックで抜ける。
5.①のフラグクリアが走り、Clickイベントを抜ける。
6.OSに制御が戻り、キューに溜まっていた②のチェックが行われ、②のClickイベントが走る。
7.5でフラグが既にクリアされているので、フラグチェックを抜ける。
8.②の処理が走ってしまう。
つまり、処理にDoEventsが入っていないため、キューに溜まったほかのチェックボックスの
チェックメッセージが①の処理が終わるまで実行されないのが
そもそもの原因ですので、上記の5の前でキューに溜まったメッセージを
処理させてやれば解決するはずです。
つまり、ねろさんのコードにつけたしで、
chk_box(Index).Value = vbUnchecked
DoEvents ' ←追加
flg = False
End Sub
とやれば、うまくいくと思います。
何度もすみません。誤解をうむかもしれませんので、訂正。
> ①の処理が終わるまで実行されないのが
①のClickイベントが終わるまで実行されないのが
です。
ねろさん、聖 羅樹さんありがとうございました。
お二人のコードを追加しましたところ うまく処理が回避できるように
なりました!
いろいろ プロパティなどの変更させると
動きがあるのでチェックボックスは難しいですね(^-^;)
とても 勉強になりました。
ありがとうございましたm(_ _)m
ツイート | ![]() |