チェックボックスについて

解決


あこ  2004-12-11 01:43:24  No: 118193

お世話になります。
環境はVB6.0です。

チェックボックスを配列していで複数使用しております。
1つのチェックボックスを選択するごとに  処理を行うのですが
処理中に  他のチェックボックスを選択すると
前の処理終了後に  処理中に押されたチェックボックスの
処理が起動してしまうのですが

チェックボックスの処理が終わるまで  他のチェックボックスを認識
しないようにするためにはどうすればよろしいでしょうか?

よろしくお願いいたします。


聖 羅樹  URL  2004-12-11 01:51:53  No: 118194

チェックボックスのチェックで走る処理は時間のかかる処理なのですか?
また、その処理中でDoEventsを使っていませんか?

DoEventsがあると、その時点でキューに溜まっていたメッセージが
処理されてしまいますので、もし問題が無ければDoEventsを消してください。


聖 羅樹  URL  2004-12-11 01:56:06  No: 118195

追記:
チェックボックスのClickイベントの最初で
全チェックボックスのEnabledをFalseにして、
イベントを抜ける直前で全チェックボックスのEnabledをTrueにする
という方法もあります。
見た目的にあまり宜しくありませんが。

処理中かどうかを判定するフラグを一つ用意して、
Clickイベントの最初にそれを判定するようにするのが
一番すっきりするかと思います。


ひろ  2004-12-11 04:59:17  No: 118196

チェックボックスはValueプロパティを変更することが
Clickイベントの発生要因になりますので、その点も注意して
プログラムを見直しましょう。


あこ  2004-12-12 05:47:57  No: 118197

皆様  ありがとうございました。
処理中でDoEventsは使用していなかったので

処理前に判定するフラグを一つ用意して、
Clickイベントの最初にそれを判定するようにするようにしたのですが
やはり処理が走ってしまいました。。
一応  他に対策として
処理前に自フォームをEnabledをFalseにして
処理終了後にTrueにするなど  いろいろ試したのですが・・
まだ  回避できておりません。

申し訳ございませんが  もう少し皆様からのご意見をお聞かせ願えれば
幸いです。。宜しくお願い致します。。。


LESIA  2004-12-12 11:53:03  No: 118198

フラグでどのように判定しようとしていたのですか?
こんな感じでうまくいくと思いますが。

Private Sub Check1_Click(Index As Integer)
    Static flgCheck As Boolean

    If flgCheck Then Exit Sub

    flgCheck = True

    処理

    flgCheck = False
End Sub


聖 羅樹  URL  2004-12-12 16:38:45  No: 118199

> 処理前に判定するフラグを一つ用意して、
> Clickイベントの最初にそれを判定するようにするようにしたのですが
> やはり処理が走ってしまいました。。

フラグで回避する方法はイベント自体を回避するのではなく、
イベントが発生した時に必ず処理が走ってしまうのを防ぐための方法です。
なので、LESIAさんのレスのようにプロシージャの頭でExit Subしてやれば、
処理は走らないはずですが。
ただし、処理は走らないもののチェックは入ってしまうので、
それを元に戻さないといけないでしょう。とすると、
ひろさんのレスにあるように、またClickイベントが走ることに・・・
タイミングによってはおかしな動きをするかもしれません。
確率的にはもの凄く低い確立になるでしょうが。

やはりEnabledのTrue,Falseを切り替えるのが一番いいような気もします。

Clickイベントの中での処理は具体的にはどのようなことを
しているのですか?


LESIA  2004-12-13 03:16:33  No: 118200

あ、そういえば処理は走らないですけど、チェックは入ってしまいますね。
聖  羅樹さん、ありがとうございます。
あこさんの言っている、処理が走るというのはチェックが入ってしまう事
なのかも。

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


あこ  2004-12-13 06:27:50  No: 118201

皆様  ありがとうございます。

>Clickイベントの中での処理は具体的にはどのようなことを
しているのですか?

具体的な処理は  メッセージ関数を発行し
その判定内容により  エクセル表を作成し印刷する処理が
入っております。

エクセル表は表示せずに裏で動いています。

今は環境がないので  すぐに上記の処理を
ためしてみることはできませんが
明日  上記の方法でこころみてみます(^-^)


あこ  2004-12-14 02:25:13  No: 118202

こんにちは。
下記のコードで試してみたのですが・・
チェックされていた処理が終了すると  次のチェックされた処理が
走ってしいまいました。
・・フォームを触れないようにしたりしても  チェックはされているのですが
下記の方法以外で  なにかいい方法ありましたら  
またよろしくお願いいたします。

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


ねろ  2004-12-14 04:42:02  No: 118203

あこさん、はまりましたね(^^;
チェックボックスは結構いやらしいんです。
基本的にはこれでいいはずです。
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


あこ  2004-12-14 05:28:33  No: 118204

ねろさま  ありがとうございました。
上記のとおり  試してみました。
ブレイクポイントを設定して実行するとうまくチェック判定されるのですが・・
ブレイクポイントをはずすと  次のチェック処理が走ってしまいました。
ブレイクポイントを設定するしない実行処理が違うことなど
あるのでしょうか?


ねろ  2004-12-14 05:39:57  No: 118205

ブレークポイントはどこに設定しているのでしょうか?


あこ  2004-12-14 05:58:05  No: 118206

>   If flg = True Then
>        chk_box(Index) = vbUnchecked
>        Exit Sub
>    End If
こちらのほうにチェックしました。


ねろ  2004-12-14 07:08:35  No: 118207

ちょっとした推理物ですね。
処理させているのは、印刷とか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)


聖 羅樹  URL  2004-12-14 19:55:14  No: 118208

> ブレイクポイントを設定するしない実行処理が違うことなど
> あるのでしょうか?
結論から言えばあります。

私もねろさんのレスにあるような状況になっているのではないかと
思うのですが、ブレークポイントではなく、
Debug.Print を使って、実際どのように処理が流れているのかを
調べてみてはいかがでしょうか。
その際、フラグの状態も書き出すようにしてみては。
私はステップ実行 or ブレークポイント設定時と
実行時の動きが違う場合は、Debug.Printを使って調べています。

もしかしたら、なぜフラグチェックをすり抜けてしまうのか
分かるかもしれません。


聖 羅樹  URL  2004-12-14 22:17:43  No: 118209

よく考えてみましたら、当たり前のことを見逃していましたので、追記。

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

とやれば、うまくいくと思います。


聖 羅樹  URL  2004-12-14 22:20:06  No: 118210

何度もすみません。誤解をうむかもしれませんので、訂正。

> ①の処理が終わるまで実行されないのが
①のClickイベントが終わるまで実行されないのが

です。


あこ  2004-12-15 17:52:39  No: 118211

ねろさん、聖  羅樹さんありがとうございました。
お二人のコードを追加しましたところ  うまく処理が回避できるように
なりました!
いろいろ  プロパティなどの変更させると
動きがあるのでチェックボックスは難しいですね(^-^;)
とても  勉強になりました。
ありがとうございましたm(_ _)m


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加