Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


6133 / 13646 ツリー ←次へ | 前へ→

【47031】DoEventsとは 烏鷺 07/2/26(月) 3:09 お礼[未読]
【47032】Re:DoEventsとは ichinose 07/2/26(月) 7:56 発言[未読]
【47042】Re:DoEventsとは 烏鷺 07/2/26(月) 18:24 お礼[未読]
【47033】Re:DoEventsとは neptune 07/2/26(月) 9:19 発言[未読]
【47034】Re:DoEventsとは りん 07/2/26(月) 9:35 発言[未読]
【47035】Re:DoEventsとは neptune 07/2/26(月) 12:13 発言[未読]
【47043】Re:DoEventsとは 烏鷺 07/2/26(月) 18:38 お礼[未読]
【47037】Re:DoEventsとは Kein 07/2/26(月) 15:55 発言[未読]

【47031】DoEventsとは
お礼  烏鷺  - 07/2/26(月) 3:09 -

引用なし
パスワード
   りんさん、ご丁寧にリンクはっていただいてありがとうございました。
しかし、やはりよく分かりません。

KESUNAさんに「甘えだべサ」と訛って揶揄されましたが、このヘルプが具体的に分かるレベルなら質問しませんよ。
このコーナーの過去レスから使用例はいくつか見ましたが、それがどういう役目をしているのか?どういう場面だから使う必要があったのか?が分からないのです。

分かりやすい具体例で説明してくださる親切な方はおいでになりませんでしょうか?それはやはり甘えでしょうか?

【47032】Re:DoEventsとは
発言  ichinose  - 07/2/26(月) 7:56 -

引用なし
パスワード
   おはようございます。

MS社のHelpは私もわかりづらい記述だと思っています。
(というより、ソフトウェアのマニュアルって全体的にわかりづらいよね)
特に勉強をやりはじめだと殊にそう感じると思います。

よって、自分が記述する時は「もっとわかりやすく記述しよう」
という気になりますよね!!

DoEvents 制御をWindowsに戻すフロー制御関数とあります。

Windowsに制御を戻した事による結果は、その時の処理によってケースバイケースです。

例1

新規ブックの標準モジュールに

Sub test1()
  Cells.Clear
  Range("A1").Select
  SendKeys "aaa" & Chr(13)
  Range("A2").Value = Range("A1").Value
End Sub

'上記のコードセルA1を選択してSendkeysステートメントで文字を送っています。
'その後A1の内容をA2に移行する、よってセルA2にも「aaa」と表示される
'ことを想定していますが、A2は空白のままですよね?

Sub test2()
  Cells.Clear
  Range("A1").Select
  SendKeys "aaa" & Chr(13)
  DoEvents
  Range("A2").Value = Range("A1").Value
End Sub

'上記のようにDoeventsを入れると想定どおり、セルA2にも「aaa」と表示される
’Sendkeysは、Windowsに制御は移らないと実行されません。つまり、test1では、
'test1の実行が終了後にSendkeysが実行されます。
'test2では、Doeventsを入れることで制御フローを変更しています。


例2 極簡単なストップウォッチを作ります

新規ブックのSheet1に「コントロールツールボックス」のコマンドボタンを
二つ配置してください(セルA1にボタンを重ねないこと)

Commandbutton1  --- セルA1に時刻を表示し続ける

Commandbutton2  --- 時刻を表示を中止する
 

Sheet1のモジュールに
'==========================================================
Option Explicit
'=================================================================
Private stop_ev As Boolean
Private Sub CommandButton1_Click()
  stop_ev = False
  Range("a1").NumberFormatLocal = "hh:mm:ss.00"
  Do Until stop_ev = True
    Range("a1").Value = [Now()]
    DoEvents
    Loop
End Sub
'==================================================================
Private Sub CommandButton2_Click()
  stop_ev = True
End Sub


上記のCommandButton1_Clickでループ中にDoeventsがあることで
時刻が表示中でもCommandbutton2をクリック可能になっています。
Doeventsを抜いて、動作の違いを確認してください。

【47033】Re:DoEventsとは
発言  neptune  - 07/2/26(月) 9:19 -

引用なし
パスワード
   ▼烏鷺 さん:
こんにちは
>KESUNAさんに「甘えだべサ」と訛って揶揄されましたが・・・省略
確かにこれはひどいな。。。

>分かりやすい具体例で説明してくださる親切な方はおいでになりませんでしょうか?それはやはり甘えでしょうか?
甘えといえば甘えです。例えばGoogleで検索して、片っ端から読み倒しましたか?
やはり自分での努力は必要です。
とはいうものの、あのHelpの内容では判らないのが普通と思いますし、
(私は最初はへぇ〜・・・?という感じでした。)
判ったと思い込む方のもどうかなと思います。

で、本題ですが、ichinoseさんが書かれてるようにこのHelpの内容は難しく、
理解するには、結構Windowsの知識が必要です。

私のわかる範囲で書くと、Windowsの全ての作業ではメッセージという
命令が飛び交っています。で、重い処理(この場合は文字列を書くだったかな?)
だとメッセージも沢山飛び交い、時間も掛かります。

 そのような場合、自分のアプリケーションのメッセージが全て処理されない
うちに自分のアプリケーションの次のメッセージが処理されてしまうとか、
他のアプリケーションのメッセージの処理を始めてしまうことがあります。
Windowsでは沢山のアプリケーションが常に動作してますからね。

このような場合に処理されず、たまったメッセージを処理させる為にDoEvents
を使用します。
 働きは、メッセージがたまっているかどうかをチェックし、たまっている
メッセージを処理する。即ち、処理できてない作業を処理すると言う働き
をします。

これがHelpではWindowsに制御を渡すと表現されています。

・・・・で、処理できなかった作業(この場合は描画ですね。)を実行させる
ことが出来るというわけです。

識者の方々>
大筋としては外れてないと思いますが、間違い、補足があれば宜しくお願い
します。

【47034】Re:DoEventsとは
発言  りん E-MAIL  - 07/2/26(月) 9:35 -

引用なし
パスワード
   おはようございます。

>・・・・で、処理できなかった作業(この場合は描画ですね。)を実行させる
>ことが出来るというわけです。
これを、前回リンク先を示したおしえてGooの(良)回答にも書いてあるので、読んでないだろうなあ・・・と。

昨日のとは別のところですが。
h t t p://officetanaka.net/excel/vba/tips/tips23.htm
そこから引用
時間のかかる処理を行っていると、CPUがその処理に没頭してしまい、その他の操作ができなくなる場合もあります。そうすると、せっかく用意した[終了]ボタンもクリックすることができなくなってしまいます。それを防ぐために、DoEvents関数を実行してCPUの処理を解放してやります。

【47035】Re:DoEventsとは
発言  neptune  - 07/2/26(月) 12:13 -

引用なし
パスワード
   ▼りん さん:
こんにちは

>>・・・・で、処理できなかった作業(この場合は描画ですね。)を実行させる
>>ことが出来るというわけです。
>これを、前回リンク先を示したおしえてGooの(良)回答にも書いてあるので、読んでないだろうなあ・・・と。
見てきました。詳しく書いてますねぇ〜。
でも、私の説明も大筋では間違ってなくってホッとしました。^ ^;

>そこから引用
>時間のかかる処理を行っていると、CPUがその処理に没頭してしまい、その他の操作ができなくなる場合もあります。そうすると、せっかく用意した[終了]ボタンもクリックすることができなくなってしまいます。それを防ぐために、DoEvents関数を実行してCPUの処理を解放してやります。

こちらの解説の方が専門用語がなくてわかりやすいかもしれませんね。

ところで私もググって見たんですが、doeventsをCで書くとこんな感じ
というのを見つけました。
わかる人にはこれが一番わかりやすいかもしれません。

VB友の会の古い過去ログから転用。

MSG msg;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
※お決まりの内容なので転載問題なしと判断しました。

【47037】Re:DoEventsとは
発言  Kein  - 07/2/26(月) 15:55 -

引用なし
パスワード
   Windowsは「見た目では何もソフトを起動していない」状態であっても
常に何らかの処理をし続けているらしいです。それは以下のようなマクロ
によって、実行中のウィンドウタイトルを列挙してみれば分かります。

Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, _
lPalam As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Sub RefreshWinList()
  Dim dumb As Boolean
  
  dumb = EnumWindows(AddressOf EnumWinProc, 0&)
End Sub

Function EnumWinProc(ByVal hWndX As Long, _
lParam As Long) As Boolean
  Dim Name As String
  Dim Leng As Long, Ret As Long

  Name = String(250, Chr(0))
  Leng = Len(Name)
  Ret = GetWindowText(hWndX, Name, Leng)
  Debug.Print Name
  EnumWinProc = True
End Function

で、そこへ何かのソフト(マクロを実行する前提だから、常識的にExcelは入る)
を立ち上げて処理を始めると、Windowsはそれに対して重点的にメモリーや
CPUの働きを割り当てるようにします。これはOSに限ったことではないのですが、
「同時に複数の処理を進める」ということが出来ないため、必要な処理を並べて
はいるが、ユーザーの求めに応じて(というか推測して?)自動的に優先順位を決め、
その順位の高いものにはより長い時間をシェアする、というような仕組みに
なっているらしいのです。となるとExcelのマクロを実行中は、必然的にExcel
の処理が多くなるため、Windows自身が出すメッセージの処理が後回しにされて
しまいます。例えばIEを立ち上げても、そのイベントを知らせるメッセージなどは
滞ることになるわけです。そこでIEが現在どのような処理をしているか ? という
ことを逐次Windowsに問い合わせるため

Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
ie.Navigate url
Do While ie.Busy
  DoEvents
Loop
Do While ie.ReadyState <> 4
  DoEvents
Loop

などとして、ある条件を満たすまでループするようにします。
>分かりやすい具体例
とのことですが、上のコードは掲示板でも良く見かけると思います。

【47042】Re:DoEventsとは
お礼  烏鷺  - 07/2/26(月) 18:24 -

引用なし
パスワード
   ▼ichinose さん:

丸投げ質問のようで失礼しました。
また大変お手数をおかけしました。

お陰さまで、ichinoseさんの説明を読み、わざわざ書いていただいたコードを実行してみて納得できました。
すばらしく解り易かったです。

もう一度過去レスを検索して、DoEventsをどうして使っているのかを検証して勉強します。
本当に優しく扱っていただけて感謝の気持ちでいっぱいです。
ありがとうございました。

【47043】Re:DoEventsとは
お礼  烏鷺  - 07/2/26(月) 18:38 -

引用なし
パスワード
   ▼neptune さん:
 
ご親切に教えていただきまして、ありがとうございました。
お陰さまで、何とか概要を掴めたような気がします。
それに、ichinoseさんのコードを実行してみて、具体的に分かりました。
今後ともよろしくご指導ください。

6133 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free