エクセルマクロVBAを使ってグラフをリアルタイムで描画する

資料請求番号:SH44

グラフアニメーションをVBAで作成する

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秒止まるという文です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です