1。はじめに
簡単なエクセル・マクロを使って、アニメーションを作成し、遊びたい。ボタンをクリックすると、右端の大砲から弾が飛び出し、左端にたまってゆく(図1)。全部で9個の弾が左端にたまると、ひとかたまりとなって右に移動し、大砲を飲み込んでしまう(図2)。そんなアニメーションを作ってみたい。
前回の例題「アルバイト賃金計算」で、セルの文字(数字)を読み込んだり、セルに文字を書き出しだりできるようになった。そんな簡単な機能を繰り返し行うことで、できるはずである。
2。作り方
まずボタンをひとつ作成する(参照「アルバイト賃金計算」)。
つぎに、そのボタンのなかに下記プログラム(Excelマクロ)を書き込む。
3。プログラム詳細
コピー&ペーストして、自作ボタンのマクロに組み込めます。
Sub ボタン1_Click()
Range("A1:T20").ClearContents
Range("R2:T2") = "■"
For i = 1 To 9
Cells(2, 21) = "■"
Cells(2, 18) = ""
Cells(2, 21) = ""
Cells(2, 18) = "■"
For j = 0 To 13
Cells(2, 17 - j) = "●"
Cells(2, 17 - j) = ""
Next j
k = Int((i - 1) / 3) + 1
L = ((i + 2) Mod 3) + 1
Cells(k, L) = "●"
Next i
Range("R2:T2").ClearContents
Range("A1:C3") = "■"
Range("A1:C3") = "□"
Range("A1:C3") = "■"
Set newR = Range(Cells(1, 1), Cells(3, 3))
For i = 2 To 18
Set oldR = newR
Set newR = Range(Cells(1, i), Cells(3, i + 2))
oldR.Value = "□"
newR.Value = "■"
Application.Wait (300)
Next i
For i = 1 To 15
Range(Cells(1, i), Cells(3, i + 2)).ClearContents
Application.Wait (300)
Next i
Range("R1:T1").ClearContents
Range("R3:T3").ClearContents
End Sub
4。プログラム概要
プログラムは2つのシナリオから成っている。まずは、大砲が弾を発射する部分から、解説する。
(図1対応部分) ひとつの弾が右から左へ移動するには、各セルに黒丸印を書き込んでゆけばよい(Cells(2, 17 - j) = "●")。しかし、ただ書き込んでゆくと、黒丸がつながってしまい、飛んでいるようには見えない。通過したセルの黒丸は消さねばならない(Cells(2, 17 - j) = "")。次のコードは、ひとつの弾が右から左へとんでゆくコードである。
For j = 0 To 13
Cells(2, 17 - j) = "●"
Cells(2, 17 - j) = ""
Next j
さて、弾は全部で9つ発射するから、上記コードを、さらに繰り返し構文で囲んでいる。
For i = 1 To 9
(ア)
For j = 0 To 13
Cells(2, 17 - j) = "●"
Cells(2, 17 - j) = ""
Next j
(イ)
Next i
ただし、(ア)は大砲がふるえるところ、(イ)は弾がたまってゆくところです。
後者の「弾がたまる」部分(イ)は、ちょっと数学的です。たとえば、4個目の弾は、第2行第1列のセルに配置したいのです。そこで、ここでは「変数iを3で割ったときの商と余り」を利用しています。
i=4を3で割ったら、商が1だから、それに1を加えて k=2
i=4を3で割ったら、余りが1だから、それを使って m=1
と計算し、k行m列のセルに黒丸を書くことにしたいというのが発想です。Int( )は、小数点以下を切り捨てる関数で、これで商が計算できます。Modは余りを計算する関数です。実際には、3で割った余りが3になることはないので、多少の工夫をしています。これで図1の弾の発射に関するコードが作成できます。
(図2対応部分) この部分の要点は「複数のセルにまとめて書き込んだり、移動させる」ことです。複数のセルを指定するためにRange関数を使いました。たとえば、Range("A1:C3") = "■"とすると、範囲"A1:C3"に黒丸を代入しますし、Range("R2:T2").ClearContentsとすると、範囲"R2:T2"の3つのセルを空白にします。しかし、この形のままでは繰り返し構文が使えません。ここでは、変数iに2から18までを代入したいので、Range(Cells(1, i), Cells(3, i + 2))を使っています。
さて、3×3(の全部で9個)のセルを一斉に右に移動させたいのですが、今度は、通過した範囲に白抜き四角を代入し(oldR.Value = "□")、新しい場所に黒い四角を代入する(newR.Value = "■")ことにしました。こうすると、軌跡が残ってゆく残像感がでます。
ここらあたりは技巧的です。Set oldR = newRで、古い範囲を保存しておいて、次の行Set newR = Range(Cells(1, i), Cells(3, i + 2))で、新しい範囲を指定しています。この順序が大切で、良く使われるプログラミング技法です。
関連アニメーション Javaアプレットで似たものを作るとこうなる。
go back