あそびマクロ第一作は「雪」でした。Windows95に慣れてきた頃。通勤の地下鉄の中でちらしの裏にコーディング、職場のお昼休みにパソコンに入れてテスト、さんざん試行錯誤してできあがりました。当時自宅で使っていたパソコンはMacで、Excelも使えなかったので。その頃の私の環境でプログラミング可能なのはExcelだけでした。
アスタリスクの雪がちらちらと降ってくっついて、その形を万華鏡で映したような形ができあがります。たまに雪らしい形ができます。タイトルは期待させすぎでした。
これを見て、やはり雪はただランダムに水がくっついてできるわけじゃないんだなあと思えました。
十数年ぶりのプログラミングで、無駄なことも結構やっていますがその時はそれしかできず、その後はちょっと日数があくとわけわからなくなってそのままにしてます。いつかはもっとスマートな方法で作りたいと思っていましたが、今はもっと美しい形になるのじゃないと作りたくない気分。
砂時計が矢印に変わって、あれ?雪の結晶なんて出ないじゃないか、と思ってひと呼吸おいた頃に雪の結晶(ということにしといてください)があらわれます。どうかあたたかい目で見てくださいますように。
Sub yuki()
'2001年5月27日
'箱田桂子
'雪…に見えることもたまにはあります。
'******* 注意*******
'作者はこのマクロの実行によって生じる一切について保障しませんのでご了承ください。
'何度も実行すると重くなるので、1回実行する度にExcelを終了することをおすすめします。
'安全の為マクロ実行後のブックの終了の際は保存しないでください。また、出来上がった画面を保存する場合は別のブックにコピーしたものをお使いください。
Cells.Select
Selection.Delete Shift:=xlUp
Selection.ClearContents
Selection.ColumnWidth = 1
Selection.RowHeight = 10.5
With Selection.Interior
.ColorIndex = 11
.Pattern = xlSolid
End With
Selection.Font.ColorIndex = 2
Range("A50").Select
ActiveWindow.ScrollRow = 1
Dim tate As Integer, yoko As Integer, ookisa As Byte, cc As Single, ss As Single
Dim endflg As Byte, nextflg As Byte, tonari As Byte, haba As Byte
Dim hen1 As Byte, hen2 As Byte, hen3 As Byte
Dim ido As Integer, xcore As Single, ycore As Single
Dim x1 As Single, y1 As Single, x2 As Single, y2 As Single, x3 As Single, y3 As Single
'全体の大きさを決める(必ず偶数)
Randomize
'ookisa = Int(10 * Rnd + 5) * 2
ookisa = 12
Cells(ookisa, 1) = "*" '中心
endflg = 0
haba = 5: xcore = 400: ycore = 200
'-------------------
While endflg = 0
yoko = Int(ookisa * Rnd + 1) '開始地点決定
tate = 1
If Cells(tate, yoko) = "*" Then endflg = 1 '開始地点既に*が入っていれば終了
Cells(tate, yoko) = "*"
'周囲の状況
nextflg = 0
While nextflg = 0
tonari = 0
If yoko > 1 Then If Cells(tate, yoko - 1) = "*" Then tonari = 1
If tate + yoko <ookisa + 1 Then If Cells(tate, yoko + 1) = "*" Then tonari = 1
If tate > 1 Then If Cells(tate - 1, yoko) = "*" Then tonari = 1
'隣が空いていたらそこに移動
If tonari Then nextflg = 1: GoTo kettei
Cells(tate, yoko) = ""
ido = Int(3 * Rnd) - 1
yoko = yoko + ido
If yoko <1 Then yoko = 2
If ido Then GoTo yokoido
tateido:
If tate Mod 2 = yoko Mod 2 Then
tate = tate + 1
Else
' tate = tate - 1 'この行やる暇ある?
If tate <1 Then tate = 1
GoTo kettei
yokoido:
If yoko <1 Then yoko = 2 '左端
If tate + yoko > ookisa And ido > 0 Then yoko = yoko - 1 '右端
Cells(tate, yoko) = "*"
Wend 'nextflg onで終了
Wend 'endflg onで終了
'-------------
For tate = ookisa - 2 To 1 Step -1
For yoko = (tate Mod 2) + 1 To ookisa - tate + 1 Step 2
hen1 = 0: hen2 = 0: hen3 = 0
'隣と同じかどうか
If yoko > 1 Then If Cells(tate, yoko) <> Cells(tate, yoko - 1) Then hen1 = 1 '\
If tate + yoko <ookisa Then If Cells(tate, yoko) <> Cells(tate, yoko + 1) Then hen2 = 1 '/
If tate > 1 Then If Cells(tate, yoko) <> Cells(tate - 1, yoko) Then hen3 = 1 '-
If tate = 1 Then If Cells(tate, yoko) = "*" Then hen3 = 1
'隣と違えば線を引く
For tonari = 1 To 6 'tonari再利用:円を六等分
For ido = -1 To 1 Step 2 'ido再利用
cc = Cos(tonari / 3 * 3.14)
ss = Sin(tonari / 3 * 3.14)
x1 = xcore + ((ookisa - tate) * cc + (yoko - 1) / 2! * ss * ido) * haba
y1 = ycore + ((ookisa - tate) * ss - (yoko - 1) / 2! * cc * ido) * haba
x2 = xcore + ((ookisa - tate + 1) * cc + (yoko - 2) / 2! * ss * ido) * haba
y2 = ycore + ((ookisa - tate + 1) * ss - (yoko - 2) / 2! * cc * ido) * haba
x3 = xcore + ((ookisa - tate + 1) * cc + yoko / 2! * ss * ido) * haba
y3 = ycore + ((ookisa - tate + 1) * ss - yoko / 2! * cc * ido) * haba
If hen1 Then
ActiveSheet.Shapes.AddLine(x1, y1, x2, y2).Select
Selection.ShapeRange.Line.ForeColor.SchemeColor = 41
Selection.ShapeRange.Line.Visible = msoTrue
End If
If hen2 Then
ActiveSheet.Shapes.AddLine(x1, y1, x3, y3).Select
Selection.ShapeRange.Line.ForeColor.SchemeColor = 41
Selection.ShapeRange.Line.Visible = msoTrue
End If
If hen3 Then
ActiveSheet.Shapes.AddLine(x2, y2, x3, y3).Select
Selection.ShapeRange.Line.ForeColor.SchemeColor = 41
Selection.ShapeRange.Line.Visible = msoTrue
End If
Next ido
Next tonari
Next yoko
Next tate
Range("A1").Select
End Sub