[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/04/21(Thu) 14:08
投稿者名:しげちー
Eメール:
URL :
タイトル:
DoEventsについて
どなたかご存知の方がいらしたら教えて下さい。

Win2000 Execel2000のVBAで『DoEvents』の仕様に関してなのですが
MSDNライブラリや他のサイト等を見た限り
一度宣言すれば、制御をアプリケーションから別処理に渡し
キューに溜まっている処理が実行されると思っています。

例えば再描画を行う処理

CommandButton1.Enabled=False

do while
    処理
loop

−@−

MsgBox

CommandButton1.Enabled=True

このままだとボタンのEnabledがきちんと描画されないので
@の個所に『DoEvents』を入れ再描画させるのは分かるのですが
これが『DoEvents』を入れただけでは反映されません。

DoEvents
DoEvents

と連続させるかTimerなどを使用しループさせないと駄目みたいです…
DoEventsは溜まったキューの内容を処理するはずなのに
何故一度ではきちんと反映されないのでしょうか!?
宜しくお願いします。

投稿時間:2005/04/21(Thu) 15:50
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: DoEventsについて
投稿された説明だけでは意味(理由)が解りません。
しいて言うなら貴方のDoEventsの使い方がそのようになっているからです。
> キューに溜まっている処理が実行されると思っています。
正しくは、発生したイベントがオペレーティング システムによって処理されるように、
プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。
従って、DoEvents を実行した時だけしか処理されません。
(溜まっている処理をすべて処理する訳ではありません)
その後は、その後のプログラムを処理します。

貴方の言っている事象を再現できるコードを投稿されない限り、これ以上は判断できません。

投稿時間:2005/04/21(Thu) 16:14
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^2: DoEventsについて
回答頂きありがとうございます。

> 投稿された説明だけでは意味(理由)が解りません。
分かりにくい説明だったようで申し訳ありません。

> 貴方の言っている事象を再現できるコードを投稿されない限り、これ以上は判断できません。
下記がコードです

Private Sub CommandButton1_Click()
    Dim i As Integer
    
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    
    For i = 1 To 10000
        Me.Cells(i, 1) = 1
    Next
    
    DoEvents
    
    MsgBox "終了"
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
End Sub

Private Sub CommandButton2_Click()
    Me.Cells(1, 1) = ""
End Sub

動作として、CommandButton1を押した際に
CommandButton1、CommandButton2共にEnabledがFalse表記に描画される
…のつもりなのですが
実際にはCommandButton2のEnabled表記はずっとTrueのように見えています。

> しいて言うなら貴方のDoEventsの使い方がそのようになっているからです。
> プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。
> 従って、DoEvents を実行した時だけしか処理されません。
この書き方では描画がされないのは当たり前なのでしょうか!?

投稿時間:2005/04/21(Thu) 20:25
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: DoEventsについて
>     CommandButton1.Enabled = False
>     CommandButton2.Enabled = False
>    
>     For i = 1 To 10000
>         Me.Cells(i, 1) = 1
>     Next
>    
>     DoEvents
>    
>     MsgBox "終了"


下記のようにしないとループが終わるまで DoEvents が実行されないでしょう。

     CommandButton1.Enabled = False
     CommandButton2.Enabled = False
     DoEvents
     For i = 1 To 10000
         Me.Cells(i, 1) = 1
     Next
     MsgBox "終了"

投稿時間:2005/04/22(Fri) 10:06
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^4: DoEventsについて
> 下記のようにしないとループが終わるまで DoEvents が実行されないでしょう。
>
>      CommandButton1.Enabled = False
>      CommandButton2.Enabled = False
>      DoEvents
>      For i = 1 To 10000
>          Me.Cells(i, 1) = 1
>      Next
>      MsgBox "終了"

レス遅くなりすみません。

ループが終わるまで DoEvents が実行されないという事ですが
実際それは構わないです。
問題はメッセージボックスが開いた状態までいっているのに
ボタンのEnabled表記がFalseのままという事でして
ちなみに花ちゃんのコードで行っても同じ状態です。

最初にも明記しましたが、DoEventsを複数回行う事により
再描画されるのは分かってるのですが、
一度実行しただけでは反映されない理由が不明だったので質問した次第です。

投稿時間:2005/04/22(Fri) 10:14
投稿者名:だい
Eメール:dee_bassist@hotmail.com
URL :http://homepage2.nifty.com/Dee/
タイトル:
Re^5: DoEventsについて
> 問題はメッセージボックスが開いた状態までいっているのに
> ボタンのEnabled表記がFalseのままという事でして

MsgBoxが開いている間は、次の行は実行されません(そういう仕様です)。
EnabledをTrueにしてからMsgBoxを出すようにしてみてください。

この場合、DoEventsは全く関係が無いものと思われます。

投稿時間:2005/04/22(Fri) 13:12
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^6: DoEventsについて
> > 問題はメッセージボックスが開いた状態までいっているのに
> > ボタンのEnabled表記がFalseのままという事でして
すみません 肝心な部分の書き間違いをしていました(汗

ボタンのEnabled表記が【True】のままという事でして

と言いたかったのです 申し訳ありません

投稿時間:2005/04/22(Fri) 14:58
投稿者名:だい
Eメール:dee_bassist@hotmail.com
URL :
タイトル:
Re^7: DoEventsについて
前回投稿時に書き忘れましたが、
当方環境(Win2000ProSP4 + Excel2000SP3 ノートPC P3-800MHz Mem128MB)
で、DoEvents無しでもEnabled = Falseは、即座に効いています。
以下、検証コード
Private Sub CommandButton1_Click()
    Dim i As Integer
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False

    For i = 1 To 10000
        Me.Cells(i, 1) = 1
    Next
    MsgBox "終了"
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
End Sub

もし、マシンのスペックや他の処理と関連したCPU負荷等の問題であれば、
花ちゃんさんのNo.2984で既に述べられている様に、
DoEventsは1回で効くとは限りませんので、
必要に応じて数回DoEventsを繰り返すことも必要な場合がありえますね。

投稿時間:2005/04/22(Fri) 15:47
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^8: DoEventsについて
環境は(Win2000ProSP4 + Excel2000SP3 DELLPC P3-800MHz Mem256MB)なのですが

> で、DoEvents無しでもEnabled = Falseは、即座に効いています。
動作としてはその方がありがたいのですが、そうはならないの。。。

> もし、マシンのスペックや他の処理と関連したCPU負荷等の問題であれば、
> 花ちゃんさんのNo.2984で既に述べられている様に、

>>発生したイベントがオペレーティング システムによって処理されるように、
>>プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。
>>従って、DoEvents を実行した時だけしか処理されません。
>>(溜まっている処理をすべて処理する訳ではありません)

> DoEventsは1回で効くとは限りませんので、
> 必要に応じて数回DoEventsを繰り返すことも必要な場合がありえますね。
この部分が理解出来てないのだと思います
仕様なら仕様でどういう状況、場合なら効かないのでしょうか?
それが分かればスッキリです^^;

投稿時間:2005/04/22(Fri) 15:53
投稿者名:しげちー
Eメール:
URL :
タイトル:
ありがとうございました
より良い方法が分かったのでそちらに変える事にしました

だいさんどうもありがとうございました

(惜しむらくは謎が謎のまま…)

投稿時間:2005/04/22(Fri) 10:48
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^5: DoEventsについて
貴方は1回1回質問内容が違うように思いますが。
No.2985 では下記のように書いていましたよね

> 動作として、CommandButton1を押した際に
> CommandButton1、CommandButton2共にEnabledがFalse表記に描画される
> …のつもりなのですが
> 実際にはCommandButton2のEnabled表記はずっとTrueのように見えています。
CommandButton2のEnabled表記はずっとTrue というのは

     CommandButton1.Enabled = False
     CommandButton2.Enabled = False
     DoEvents
このようにすれば解消されたはずです。

それがNo.2990では下記のように言って。
> ループが終わるまで DoEvents が実行されないという事ですが
> 実際それは構わないです。

又、違う事を言っているし
> 問題はメッセージボックスが開いた状態までいっているのに
> ボタンのEnabled表記がFalseのままという事でして
その前にTrue にどこかで設定していますか?
私は、そのように貴方がコードを書いたものと判断しておりました。
(処理が終了したら MsgBox を表示して OK が返ったら ボタンを True に
する仕様)
ループが終わったらすぐにボタンをTrue にしたければ なぜ、MsgBox を表示する前に
書かないのですか?
だい さんが回答されているように DoEvents とは何の関係もない事です。

下記で試して見て下さい
Private Sub CommandButton1_Click()
    Dim i As Integer
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    DoEvents
    For i = 1 To 10000
        Me.Cells(i, 1) = 1
    Next
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
    MsgBox "終了"
End Sub

投稿時間:2005/04/22(Fri) 13:21
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^6: DoEventsについて
> 貴方は1回1回質問内容が違うように思いますが。
> No.2985 では下記のように書いていましたよね
抜本的な誤解を招くようなミスをして申し訳ありませんでした

> CommandButton2のEnabled表記はずっとTrue というのは
>
>      CommandButton1.Enabled = False
>      CommandButton2.Enabled = False
>      DoEvents
> このようにすれば解消されたはずです。
ここで解消されていません
CommandButton2ボタンの表記は一貫してTrueのままです

行いたい動作としては
@CommandButton1ボタンを押す
 →CommandButton2のEnabledがFalseになる
AMsgboxのOKを押す
 →CommandButton2のEnabledがTrueになる
です
この@の処理がDoEventsを一度実行しただけでは描画されないという事です
度々の繰返し質問ですみません

投稿時間:2005/04/22(Fri) 14:25
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^7: DoEventsについて
      CommandButton1.Enabled = False
      CommandButton2.Enabled = False
      DoEvents

でも False にならないなら 一度下記のように設定して試して見て下さい。

      CommandButton1.Enabled = False
      CommandButton2.Enabled = False
      CommandButton1.Refresh()
      CommandButton2.Refresh()

投稿時間:2005/04/22(Fri) 14:54
投稿者名:しげちー
Eメール:
URL :
タイトル:
Re^8: DoEventsについて
>       CommandButton1.Refresh()
>       CommandButton2.Refresh()
すみません、これって宣言とか必要なんですか?
コンパイルの時点で通らないのですが。。。

ちなみにこの処理で描画の処理が問題なく行えたとしても
当初の質問であったDoEventsの実行が反映されない謎は謎のままでしょうか!?

投稿時間:2005/04/22(Fri) 15:12
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^8: DoEventsについて
ごめんなさい VBA でしたね Refresh がなかったのですね。

Refresh の変わりに ボタンを貼り付けているシートを一度アクティブに
してみるとかしてもおなじでしょうか?

投稿時間:2005/04/22(Fri) 15:22
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^8: DoEventsについて
私の環境で試したら CommandButton2 だけが  Enabled = False にならないのですね
下記のように一度フォーカスを移してやる事で Enabled = False になりました

Private Sub CommandButton1_Click()
    Dim i As Integer
    CommandButton1.Enabled = False
    CommandButton2.Enabled = False
    
    CommandButton2.Activate
    
  '  DoEvents
    For i = 1 To 10000
        Me.Cells(i, 1) = 1
    Next
    CommandButton1.Enabled = True
    CommandButton2.Enabled = True
    MsgBox "終了"
End Sub

投稿時間:2005/04/22(Fri) 15:50
投稿者名:しげちー
Eメール:
URL :
タイトル:
解決しました
> 私の環境で試したら CommandButton2 だけが  Enabled = False にならないのですね
> 下記のように一度フォーカスを移してやる事で Enabled = False になりました

>     CommandButton2.Activate
確かにこのコードの方が動作にもタイムラグもなく適切だと思いました。
こちらの処理方法にします。

花ちゃんさんどうもありがとうございました。