資料請求番号:SH44
CONTENTS
VBAを走らせている間、基本的にExcelの画面は固まってしまいます。
実行中に値が出力されたとしても、それがグラフに反映されるのはVBAの処理が全て終わってからになります。
本記事では、VBAを走らせながら、リアルタイムで計算結果をグラフで表示することによって、グラフアニメーションを作成するためにはどうすればよいのかをまとめました。
例題として、以下のような動画をVBAで作ることを目指します。
なぁ、シママ、ちょっと遊びでな、正葉曲線って言うのを描いてみたんやがな。
あら、かわいい♪四つ葉のクローバー♪
あぁ、それでな、このグラフができるところを動画に撮りたいっつーか・・・。
どういうこと・・?
えっとな・・・θ=0からπ/4まで描くと左の図やろ?π/2まで描くと右の図やろ?こういうのを大量に作って、動画化して、
曲線が伸びて最後に四つ葉ができるところを表現したいねん。
あ~!グラフがヌルヌル伸びてくのを表現したいのね!!
せやせや!
そうなるとね、アルゴリズム的にはB列からE列をグングン伸ばしていく感じになるのよね。
どこまで伸ばしたい?
100行でちょうどθが2πになるようになってるから、100行までやな。
じゃあ、こんな感じでどうかしら?
/* –Rose curve Realtime plot ——– */
Sub plot_realtime()
Range(Cells(3, 2), Cells(3, 5)).Select
nmax = Cells(2, 8)
For i = 1 To nmax
j = i + 3
Selection.AutoFill Destination:=Range(Cells(3, 2), Cells(j, 5)), Type:=xlFillDefault
Next i
End Sub
/* –Rose curve Realtime plot ——End– */
Selection.AutoFill・・・ってあるでしょ?
これは、グラフを伸ばすときにこういう作業するでしょ?
するする!これをダバーッ!!と伸ばしてグラフの概形描くたいね。
Selection.AutoFill・・・の文はそれを自動化しているのよ。
Range(Cells(3, 2), Cells(3, 5)).SelectでB3~E3を選択して、
iが1のとき、jは4になってるから、Cells(4, 5)、即ちE4まで引き延ばされる。
ループが周るにつれてjはどんどん大きくなって、最終的に、
iが100の時はjが103になってて、Cells(103, 5)、即ちE103まで引き延ばされる。
そしたら1刻みで100分割してθ=2πまで描けてるでしょ?
せやな。1ループ毎に引き延ばせたら、1ループごとにグラフができて、グラフがリアルタイム表示できそうなやぁ~
やってみたら?
・・・できん。
・・・・。
オマエ、できんことわかってて、「やってみたら」言うたやろ!!?
えへへっ♪ ゴメンね♪
あのね、VBAのプログラム回している間はExcelの制御を完全にVBAに渡している状態になるの。
だから、時間のかかるマクロを回している間はExcelがフリーズしたみたいな感じになるのよね。
ふぅ~ん。
それで一旦制御をOSに返しますっていう命令を書かなきゃいけないの。それがDo Events関数。
これを入れてやってみなよ。制御がOSに返ったらグラフを描くことができるから。
/* –Rose curve Realtime plot ——– */
Sub plot_realtime()
Range(Cells(3, 2), Cells(3, 5)).Select
nmax = Cells(2, 8)
For i = 1 To nmax
j = i + 3
Selection.AutoFill Destination:=Range(Cells(3, 2), Cells(j, 5)), Type:=xlFillDefault
DoEvents: DoEvents: DoEvents
Next i
End Sub
/* –Rose curve Realtime plot ——End– */
おお~っ!できた~!スゲェ~!!
計算結果をリアルタイムでプロットするのに重要な役割をするのがDo Events関数なのよ。
あとは、飾りつけみたいにこうしたら、もうちょっとカッコがつくんじゃない?あ、あと、予めグラフの体裁は整えておかないとダメだよ。
ああ、このグラフは散布図(平滑線)で以下の様にグラフの体裁を予め整えている。
/* –Rose curve Realtime plot ——– */
Sub plot_realtime()
Range(Cells(3, 2), Cells(3, 5)).Select
nmax = Cells(2, 8)
For i = 1 To nmax
j = i + 3
Selection.AutoFill Destination:=Range(Cells(3, 2), Cells(j, 5)), Type:=xlFillDefault
Cells(3, 8) = Cells(j, 2)
Cells(3, 10) = Cells(j, 3) / Cells(1, 16)
Cells(3, 13) = Cells(j, 4)
Cells(3, 15) = Cells(j, 5)
DoEvents: DoEvents: DoEvents
Next i
End Sub
/* –Rose curve Realtime plot ——End– */
おお~っ!ええなぁ!ありがとう!
VBAを使ってグラフをリアルタイムで描画し、アニメーションを作るためには、
Forループの中でグラフを1刻み伸ばす動作に加えて、Do Events関数で一旦制御をOSに返す動作を行わなければなりません。
また、ループの中でApplication.Wait [Now() + “0:00:00.1”]などと書いて、アニメーションの速度を遅らせることができます。
この文は、次の命令を行う前に0.1秒止まるという文です。