
こんにちは。
VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。
cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。
そこで下記のようなコードを入力しました。
userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1
しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。
しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」
と書いてあるのですが正直、書いてあることがよくわかりません。
どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?
よろしくお願いいたします。

No.2ベストアンサー
- 回答日時:
簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。
注意点ですが、
Private Sub CommandButton1_Click()
Dim i As Long
For i = 1 To 50000
DoEvents
Cells(i,1) = ""
Next i
End Sub
Private Sub CommandButton2_Click()
MsgBox "hoge"
End Sub
っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。
これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。
Private Canceled As Boolean
Private Sub CommandButton1_Click()
CommandButton2.Enabled = False
Dim i As Long
For i = 1 To 50000
DoEvents
If Canceled = True Then
MsgBox "キャンセルしました"
Exit Sub
End If
Cells(i, 1).Value = ""
Next i
End Sub
Private CommandButton2_Click()
Canceled = True
End Sub
コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。
temtecomai2さん
とても詳しい御回答どうもありがとうございました。
今回、『再描画』という意味を初めて知りました。
勉強になります!
temtecomai2さんの書いていただいたコードをコピペしてみて
試してみました!
おかげ様でDoEventsの効果がよくわかりました。
それとDoEventsを入れるのと入れないのでは処理速度も違うんですね。
下の例ではDoEventsを入れた方は78秒、入れなかったほうは25秒でした。
これって制御をOSに渡す時間が下のコードの例では53秒(78-25)も掛かるって事なんでしょうか?
No.8
- 回答日時:
No.7 の件について
このカテゴリーがVisual Basicの為、うっかりVBでプログラム
を作ってしまっていました。
手もとにあるExcel97とExcel2000とで作成してみましたが、
テキストボックスにGotFocusプロパティ自体無く、且つ実行
してもエラーも発生しませんでした。
(Win98SE 及びWin2000)
どうも 19746999 さんが使用しているExcel とはバージョン又
は実行環境が異なる為、動作が異なっている事が考えられ
ます。
don_goさん
こんにちは
・・しまった。。
「EXCELのVBAに関する質問」
って最初に書くの忘れていました。
ごめんなさい。これからは気をつけます・・・。
そうですね!
僕が使っているのはEXCEL2002で
VBAのバージョンは
Microsoft Visual Basic 6.0です。
結局違いがわからないままですが、
過去に書いていただいた方の
アドバイスを参考にして
理解していこうと思います。
それではあと1,2日で質問を締め切ろうと思います。
ポイントあげる人迷うなぁ・・・
No.7
- 回答日時:
間違いの例としては、あまり良いのが浮かばなかったので申し訳ありませんが...
DoEvents の有無により動作の違う例を
Private Sub Text1_GotFocus()
MsgBox "GotFocus"
End Sub
Private Sub Command1_Click()
Text1.Text = 1
Text1.SetFocus
DoEvents
MsgBox "hoge"
End Sub
don_goさん
こんにちは
具体的なご回答ありがとうございます。
・・大変申し訳ないのですが
ユーザーフォームを作って
コマンドボタンとテキストボックスを
そのユーザーフォームの上に作って
(もちろんオブジェクト名は統一させました。)
教えていただいたイベントプロシージャを
コピペして試してみたのですが、
よくわかりません。
と言うより「Gotfocus」イベントが働きません。
なのでDoeventsの有無にかかわらず動きが同じに感じます。
試しにシート上にテキストボックスを作って
教えていただいたコードを入力して
(もちろんオブジェクト名は統一させた。)
Gotfocusイベントが働くか確認するために
そのテキストボックスをクリックすると、
ちゃんとGotfocusイベントが動くのですが、
コマンドボタンをクリックしてマクロを実行すると
setfocusメソッドでのところで下記のエラーが出てしまいます。
↓
オブジェクトは、このプロパティまたはメソッドをサポートしていません。(Error 438)
いろいろ考えたのですが
どこが間違っているのかわかりませんでした。
わかりにくい質問だと思いますが
何が間違っているのか教えていただけませんか?
何度も質問してしまって申し訳ございませんが
よろしくお願いします。
No.6
- 回答日時:
DoEventsは、MS-WindowsがUNIXやLinux等のマルチタスクOSではなく、
疑似マルチタスクで有るため必要になるものです。
通常マルチタスクOSでは、同時に実行される各種のプログラムに対して
処理に必要な時間と順序をOSが配分して実行しますが、MS-Windows
ではプログラムから処理が戻ってから(今回ではプロシージャが終了して
から)、次のプログラムやキー入力、マウス入力イベント等を実行します。
従って、時間のかかる処理や無限ループなどがあると、他の処理が実行
できなくなり、極端に全体の反応が遅くなったり、動かなくなったりします。
#画面が白くなるのは、表示の更新が行われなくなるためです。
そうなる事を防ぐ為、DoEventsを実行して、他のプログラムやイベント
処理を実行させる必要があります。
但し、Form上のコントロールに対して値をセットした後、DoEventsを実行
した場合、ChangeやGetFocusイベントが実行され、思っていなかった動作
をする事があるので、使用する場所には十分注意する必要があります。
don_goさん
ご回答ありがとうございます。
たくさんのわかりやすいご回答を頂いてきましたが
更に重要な回答を投稿していただいてうれしいです。
それから、もしよろしければ
>但し、Form上のコントロールに対して値をセットした後、DoEventsを実行
した場合、ChangeやGetFocusイベントが実行され、思っていなかった動作
をする事があるので、使用する場所には十分注意する必要があります。
ごめんなさい・・・この部分もう少し詳しく教えていただけないでしょうか。
面倒くさかったら無視してください^-^
No.4
- 回答日時:
表題の>DoEvents関数って何?
について、DoEventsは関数に分類されず、「ステートメント」に分類されています。
VBAの解説書などでは、
オブジェクト
プロパティ
メソッド
ステートメント
関数
に分類されています。念のため。
意味はWEBで照会してください。
ーー
DoEventsもOKWAVEで質問して、聞くのも良いが、WEB照会したら、働きの説明も、実例も多数出てきますよ。
imogasiさん
ご回答ありがとうございました
>DoEventsもOKWAVEで質問して、聞くのも良いが、WEB照会したら、働きの説明も、実例も多数出てきますよ。
・・・本当だいっぱい出てきた。
教えていただいてありがとうございます。。。
No.3
- 回答日時:
Windowsはイベント-なにかが起きることー
(しかし、それは予期せぬものではなく約束されたもの)
が発生することにより動作します。
たとえばキーが押されたとか、時間が来たとか。
CPUは1っこしかないのでタイムシェアーでいろいろな
プログラムがイベントを発生させて動いています。
しかし、あなた(ユーザー)がそのことを考えずにプログラミング
すると、他のプログラムは自分の番が来ないので動けなくなり、
画面が真っ白になったままになったりするわけです。
最初のコードはCPUを占領します。(そうなっちゃう)
2番目のコードはDoEvents のところで一回処理を止め、
(windows に渡し)次に自分の番がきたときに、
次のステップを続けます。
当然処理速度は桁違いに遅くなります。
otto0001ottoさん
わかりやすいご回答ありがとうございました。
VBAもまだまだ未熟者ですが
パソコン全体の事はもっとド素人です。
もっとパソコンについてオールラウンドな
知識を身につけることが大切だと思いました。
これからも日々勉強を怠らずに頑張ります♪
また何かわからないことがあったら
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
DoEventsがやはり分からない
Visual Basic(VBA)
-
VBA コードを実行すると画面が真っ白になる
Visual Basic(VBA)
-
DoEventsが必要な理由について
Visual Basic(VBA)
-
-
4
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
5
SQL文で パラメータが少なすぎます エラー
Access(アクセス)
-
6
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
7
Form_Load と Form_Activate のタイミング
Visual Basic(VBA)
-
8
VB.NET版のDoEvents()を探しています
Visual Basic(VBA)
-
9
VB6で、長い時間かかる処理実行中の表示の工夫について
Visual Basic(VBA)
-
10
パラメータが少なすぎます。1を指定して下さい。""
Excel(エクセル)
-
11
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
12
【VBA】ワークブックを開く時にエラーが出る場合と出ない場合の違いは?
Excel(エクセル)
-
13
On ErrorでエラーNoが0
Visual Basic(VBA)
-
14
VBAでユーザーフォームを再表示させたい。
Excel(エクセル)
-
15
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
16
Accessで処理経過を表示したいのですが
その他(データベース)
-
17
Refreshメソッドの使い方
Visual Basic(VBA)
-
18
マクロ実行時、ユーザーフォームにラベルのテキストが表示されません。
Access(アクセス)
-
19
Designer.vbは直接コードをいじってはだめ?
Visual Basic(VBA)
-
20
特定のキーを押すまでループさせるにはどうすればよいですか。
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DoEvents関数って何?
-
プログラム上のCPU稼働率低減に...
-
VB.NETにおける二値化処理の高速化
-
小数点を含む数値かどうか判断...
-
SQLの速度をあげるには・・・
-
clispの実行方法
-
ExcelVBA処理経過をリアルタイ...
-
Typescript が必要な理由
-
実行時のCPU使用率を増やしたい
-
OpenGLでのコンター表示
-
ナップザック問題?をエクセル...
-
VBでの簡易電卓の作成(減算方...
-
C言語:関数を使うメリットとデ...
-
Excel VBA データ削除の高速化
-
Excel VBA での処理時間計測結...
-
Excel VBAにて、2GB超の点群デ...
-
C#で書かれたプログラムをバッ...
-
C言語でのUTF-8の文字列の処理...
-
Macターミナルで実行中のプログ...
-
VBSの処理中一旦処理を止めて再...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel VBAにて、2GB超の点群デ...
-
小数点を含む数値かどうか判断...
-
プログラム上のCPU稼働率低減に...
-
Excelでのセル内容の高速消去方法
-
DoEvents関数って何?
-
SQLの速度をあげるには・・・
-
win10で、正確な待ち時間の作り方
-
If Not c Is Nothing Then ~延...
-
VC++2010 GDIオブジェクトの解...
-
絶対パスの取得について
-
ノットイコールを教えて下さい
-
C言語:関数を使うメリットとデ...
-
あっち向いてホイのプログラム...
-
再帰呼び出しを使いますか?
-
Excel VBA データ削除の高速化
-
C#で書かれたプログラムをバッ...
-
c言語で自然数nを入力、2以上n...
-
異なるプログラミング言語を連...
-
再帰呼出について
-
Excel VBA での処理時間計測結...
おすすめ情報