パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

セル関連マクロ例

1 A列の終端セルを調べ、その間にある空白セルの行を削除する。

データ数が可変の列で、列の終端セルを調べ、その間に空白のセルがあればその行を全て削除したい
ということがよくあります。そんな場合に使うためのマクロの基本形です。
例えば下の表で、A3,A4が空白なので、3行、4行目を削除するというような場合です

 
5          
   
     
     
   
   
     
     
Sub CutNullrow()
x% = Worksheets("sheet1").Range("A65536").End(xlUp).Row
For i = x% To 1 Step -1
If Worksheets("sheet1").Cells(i, 1).Value = "" Then Worksheets("Sheet1").Rows(i).Delete     
Next
End Sub

非常に短いマクロですが、含蓄に富んでいます。
終端セルの取得についてはセル関連基本マクロで解説しましたので、参考にして下さい。
さて、行(ROW)の削除ですが、終端セルから若い方(セルA1)に向かって削除している点に注目して
下さい。 For i = x% To 1 Step -1 の部分です。

ここを、順当に For i = 1 To x% とやると、複数行にわたって空白セルがある場合うまくいきません。
ちょっと、上の例で考えてみます。i=3 の時3行目が削除されます。すると、4行目以下が1つ上につめられて
4行目が3行目にきます。次にi=4になった時には、空白セルの元4行目は3行目になっているので、
削除されずに残ってしまいます。

というわけで、終端セルのほうからさかのぼって削除していくのです。


2 オセロではさまれた駒をひっくり返す処理
これはおじさん自作のEXCEL OTHELOで使っているものです。EXCEL OTHELOは
EXCEL活用例(自作アプリ)からダウンロードできます。

ちょつと前置きです。このオセロでは、自分の駒は”y”、コンピューターの駒は”c”です。
オセロ盤はA1からH8までのセルです。何も置かれていないマスは”.”になっています。

  A B C D E F G H
1 . . . . . . . .
2 . . . . . . . .
3 . . . . . . . .
4 . . . y c . . .
5 . . . c y . . .
6 . . . . . . . .
7 . . . . . . . .
8 . . . . . . . .

前置きその2です

置きたいマスにおけるかどうかの判定
置きたいマスの選択は、置きたいマス(セル)をクリック(選択)することによって行わせています。
選択されたセルはActivecellになりますので、
If ActiveCell <> "." Then で駒を置けるマスかどうか判定します。

選択されたセルの行、列の取得
d = ActiveCell.Address(ReferenceStyle:=xlR1C1)
r = Val(Mid(d, 2, 1)): c = Val(Right(d, 1))
によって、自分がおいた駒の位置の行が変数r 列が変数cに入るようになっています。


では、本題の置いた駒による反転処理について、右側の処理、左側の処理のマクロをみてみます。

If ActiveCell <> "." Then
MsgBox "そこには置けません。位置を決めて下さい。", , "Excel othello"
Exit Sub
End If

d = ActiveCell.Address(ReferenceStyle:=xlR1C1)
r = Val(Mid(d, 2, 1)): c = Val(Right(d, 1))
hanten = 0: ymiss = 0
Sheets(1).Unprotect
Range("A1:H8").Locked = False
Sheets(1).Protect

' migi hanntei(右反転)
x = r: y = c + 1
Do While y <= 8
If Cells(x, y) = "y" Then
   For j = c To y
   Cells(x, j) = "y"
   Next
   If y > c + 1 Then hanten = 1
   Exit Do
ElseIf Cells(x, y) = "." Then
   Exit Do
ElseIf Cells(x, y) = "c" Then
   y = y + 1
End If
Loop

'hidari(左反転)
x = r: y = c - 1
Do While y >= 1
If Cells(x, y) = "y" Then
   For j = c To y Step -1
   Cells(x, j) = "y"
   Next
   If y < c - 1 Then hanten = 1
   Exit Do
ElseIf Cells(x, y) = "." Then
   Exit Do
ElseIf Cells(x, y) = "c" Then
   y = y - 1
End If
Loop

上の例で、F4に自分の駒をおいた場合について説明します。
この場合X=r=4, c=5、y=4となります。

Do While Y>=1   Loop は
(a)一番左(A列)に駒を置いた場合に、すぐに左反転のルーチンを抜ける。一番左に置いたら、
  左反転のしょりは必要ありませんので。
(b)一番左(A列)まで調べた場合。すなわち、左側は全て”c”だった場合に左反転ルーチンを抜ける
という処理を行います。

以下のIf文では Cells(x,y)のセルが
(a) ”c”ならy=y−1にする。 すなわち、もうひとつ左のセルのチェックに移行する
(b) ”.”ならDoループを抜ける
(c) ”y”なら置いた駒(変数cに列のデータ入っている)から、最初に出会った左側にある自分の駒(変数y
   に列のデータ入っている)の間の駒を反転する(”y”にする)
という処理をします。

F4に置いた場合の処理を言葉で表すと
今、F4におきましたので、
E4の駒を調べます。E4は”c”なので、y=y−1 して
D4の駒を調べます。D4は自分の駒”y”なので、
置いた駒F4と最初に出会った自分の駒D4の間の駒(E4)を”y”に反転します。

というわけです。
同じような処理ルーチンを、あとは上、下、斜め4方向作成すれば、反転処理は完成です。
全方向やらねばならないので、なんか、結構面倒ですね。

オセロ完成にはあとは、コンピューターの思考ルーチンをどうするかです。
こっちの方が、プログラムとしては楽しい?

TopPage > Visual BasIc&Excel活用研究目次