
こんにちは。
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で質問しましょう!
似たような質問が見つかりました
- マクロ実行時、自動で背景色を変えたい。 C列にあるチェックボックスをチェックするとB列に「TRUE」
- 列と行の名前(重複あり)が交差するセルに、データを入力したい
- VBA Userformで一部別シートに転記がしたいのですが
- 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ
- VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。
- ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています
- 列と行の名前(重複あり)が交差するセルに、データを入力したい
- vba 等間隔の列に対しての計算
- ユーザーフォームに2つのコンボボックス銀行名「ConboBox1」支店名を「ConboBox2」とし
- VBAで実行時エラー'424' オブジェクトが必要ですと出る
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
DoEventsがやはり分からない
Visual Basic(VBA)
-
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
VBAで保存しないで閉じると空のBookが残る
Excel(エクセル)
-
-
4
Application.ScreenUpdating = Falseが効きません
Visual Basic(VBA)
-
5
EXCEL VBA マクロ 実行する度に処理速度がどんどん遅くなる原因が知りたい
Excel(エクセル)
-
6
ExcelVBA実行後に時々落ちる
Visual Basic(VBA)
-
7
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
8
DoEventsが必要な理由について
Visual Basic(VBA)
-
9
VBA コードを実行すると画面が真っ白になる
Visual Basic(VBA)
-
10
エクセルVBAが途中で止まります
Visual Basic(VBA)
-
11
Form_Load と Form_Activate のタイミング
Visual Basic(VBA)
-
12
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
13
ExcelのVBA。public変数の値が消える
Visual Basic(VBA)
-
14
VBAでの一時停止と再開の方法
その他(プログラミング・Web制作)
-
15
VBA 変数名に変数を使用したい。
Visual Basic(VBA)
-
16
Accessのマクロでモジュールを実行させたい。
Access(アクセス)
-
17
VBA シートのボタン名を変更したい
Visual Basic(VBA)
-
18
《エクセルVBA》「他の人が該当ファイルを使用中の場合」の処理
Excel(エクセル)
-
19
VBAでループ内で使う変数名を可変にできないか。
Visual Basic(VBA)
-
20
エクセルVBA 「On Error GoTo 0」について
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
小数点を含む数値かどうか判断...
-
Excelでのセル内容の高速消去方法
-
DoEvents関数って何?
-
.netからexcel操作の処理速度が...
-
Excel VBA での処理時間計測結...
-
PCの並列化
-
c言語で自然数nを入力、2以上n...
-
ナップザック問題?をエクセル...
-
win10で、正確な待ち時間の作り方
-
基本情報技術者試験詳しい方へ...
-
PIC mainループについて
-
C言語 時刻差分の算出方法
-
テキストファイルの空行をスキ...
-
wavelet変換のソフト
-
SQLの速度をあげるには・・・
-
Excel VBA データ削除の高速化
-
VBでの簡易電卓の作成(減算方...
-
符号付きにすべきか、符号なし...
-
ゲームプログラミングの乱数で...
-
C#で書かれたプログラムをバッ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excelでのセル内容の高速消去方法
-
DoEvents関数って何?
-
SQLの速度をあげるには・・・
-
win10で、正確な待ち時間の作り方
-
小数点を含む数値かどうか判断...
-
WebBrowserの読み込み待ちの処...
-
Excel VBAにて、2GB超の点群デ...
-
If Not c Is Nothing Then ~延...
-
ノットイコールを教えて下さい
-
絶対パスの取得について
-
Excel(VBA)でSetTimer関数を使...
-
あっち向いてホイのプログラム...
-
ソートにかかった時間を測りたい。
-
テキストファイルの空行をスキ...
-
VBでの簡易電卓の作成(減算方...
-
ナップザック問題?をエクセル...
-
C言語:関数を使うメリットとデ...
-
C言語 再帰処理のメリットとデ...
-
異なるプログラミング言語を連...
-
ゲームプログラミングの乱数で...
おすすめ情報