ExcelマクロVBAサンプル集
オセロを作りながらマクロVBAを学ぼう№4

ExcelマクロVBAの実用サンプル、エクセルVBA集と解説
最終更新日:2019-06-16

オセロを作りながらマクロVBAを学ぼう№4


ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第4回です。


石を置ける場所の定義を、前回は文章で書きました、
今回は、それをもとにマクロVBAのプログラミングをしていきます。
考え方は決定しているので、後はVBAに翻訳(コーディング)していくだけです。

まずは、前回のまとめの確認です。

自分の石を置ける場所の判定の整理
・判定セルから、8方向に検査を進める
・8方向は、
 For i = -1 To 1
 For j = -1 To 1
 これをネストする
・1方向に向かって順に置かれている石を判定
 終了条件は、
  ・空白(石が置かれていない)
  ・自分の石が置かれている
 自分の石が置かれていて終了した時、それまでに相手の石があるか
・8方向のいずれか一つでも、上記条件を満たせば、自分の石が置ける


セルをダブルクリックした時、
そこに石が置けるかどうかを判定し、メッセージボックスを表示するようにしてみます。



シート「オセロ」のシートモジュールにダブルクリックのイベントプロシージャーを追加します。

マクロVBAの参考画像

Sheet1(オセロ)
ここをダブルクリックします。
または、右クリックから「コードの表示

マクロVBAの参考画像

この下にダブルクリックのイベントプロシージャーを追加します。

マクロVBAの参考画像

プロシージャーが追加されます。
左オブジェクト選択のドロップタ゜ウンを「Worksheet」を選択した時点で、
「Worksheet_SelectionChange」これが追加されてしまいます。
残したままでも特に問題はありませんが、削除しておきましょう。
以下のコードを追加してください。



Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  Set TarggetSheet = Sheet1
  Set 置く石 = Range("L2")
  Set 相手石 = Range("L3")
  If is置ける全方向(Target) Then
    MsgBox "置ける"
  Else
    MsgBox "置けない"
  End If
  Cancel = True
End Sub

引数の、
TargetはRangeオブジェクトです。
エクセルの根幹はセルです、セルはRangeオブジェクトになります、このRangeオブジェクトの理解なくして、マクロは理解できません。VBAの上達の試金石として、Rangeオブジェクトの理解があると言っても過言ではありません。セルを表すVBA記述は多数存在します、Range、Cells、Rows、
ダブルクリックしたセルになります。



標準モジュールに石が置けるかの判定を作ります。
マクロVBAの参考画像

Module1
ここをダブルクリック
または、右クリックから「コードの表示

Option Explicit
これだけが入っているはずなので、その下に以下のコードを追加してください。



Public TarggetSheet As Worksheet
Public 置く石 As Range
Public 相手石 As Range

Function is置ける全方向(ByVal Target As Range) As Boolean
  Dim i As Long
  Dim j As Long
  '既に石が置いてある場合は置けない
  If Target.Value <> "" Then
    is置ける全方向 = False
    Exit Function
  End If
  '8方向を順に判定
  For i = -1 To 1
    For j = -1 To 1
      If is置ける1方向(Target, i, j) Then
        is置ける全方向 = True
      End If
    Next
  Next
End Function

Function is置ける1方向(ByVal Target As Range, _
      ByVal i As Long, _
      ByVal j As Long) As Boolean
  Dim r As Long
  Dim c As Long
  Dim is置く石 As Boolean
  Dim is相手石 As Boolean
  '石を置くセルの行列位置
  r = Target.Row
  c = Target.Column
  With TarggetSheet
    '空白or置く石と同じ石が出てくるまで判定
    Do
      r = r + i
      c = c + j
      '空白(石が置かれていない)
      If .Cells(r, c) = "" Then
        Exit Do
      End If
      '自分の石が置かれている
      If .Cells(r, c).Font.Color = 置く石.Font.Color Then
        is置く石 = True
        Exit Do
      End If
      '相手の石が置かれている
      If .Cells(r, c).Font.Color <> 置く石.Font.Color Then
        is相手石 = True
      End If
    Loop
  End With
  '自分の石が置かれていて終了した時、それまでに相手の石があるか
  If is置く石 = True And is相手石 = True Then
    is置ける1方向 = True
  End If
End Function

良く使うオブジェクトを
オブジェクト変数
変数のデータ型の説明において、Object…オブジェクト型 というのがあった事を覚えているでしょうか。数値や文字ではなく、オブジェクトを入れる変数がオブジェクト変数です。オブジェクトと言っても、いろいろなものがあります。

パプリック変数
変数には、その変数をVBA内で使う事ができる範囲が決められています。マクロVBAでは変数の使える範囲を、適用範囲(スコープ)と言います。適用範囲とは、宣言した変数を使う事のできる範囲です。変数を宣言した場所と宣言方法によって、その変数を使える場所が違ってきます。
として定義しています。

Public TarggetSheet As Worksheet ・・・ オセロ盤があるシート
Public 置く石 As Range ・・・ 置く石が設定されているセル
Public 相手石 As Range ・・・ 相手の石が設定されているセル

Worksheet_BeforeDoubleClick
この中で、パブリック変数を設定してから、 「is置ける全方向」を呼び出します。
Cancel = True
これは、ダブルクリックの後にセル編集状態にならないように、イベントを終了させるためのものです。

Functionプロシージャー
プログラム(マクロVBA)内で特定の作業を実行し値を返すプロシージャです。つまり、Functionプロシージャで独自の関数をつくれるということです。Subプロシードャーとの違いは、値を返すか返さないかの違いです。
プログラム内で特定の作業を実行し、値を返すプロシージャです。
Functionプロシージャーの括弧()の中に引数が指定されています。
これは、プロシージャーに引数を渡しています。
Subプロシージャー、Functionプロシージャーにおける、引数リストの指定について説明します。引数は、呼び出し先のプロシージャーに渡すデータを指定するものです。Callステートメントでプロシージャーを呼び出すときに指定する引数を、呼び出される側のプロシージャーで受け取る記述についてのVBA記述の説明になります。

is置ける全方向
これで8方向を判定できるようにしています。
実際には3×3=9方向なのですがも行0列0の移動は石を置きたい場所なので、
既に石が置いてある場合は置けない判定で直ぐに判定が終了しています。
If is置ける1方向(Target, i, j) Then
これで、1方向でも「置ける」判定であれば、「置ける」と返すようにしています。

is置ける1方向
ここでは、「is置ける全方向」から渡された方向について判定をします。
If is置く石 = True And is相手石 = True Then
これで、相手の石があって、その先に置く石があることを判定しています。

.Font.Color
この違いで判定しているので、少しわかりずらいかもしれませんが、
個々のステートメントは極めて基本的なものだけとなっています。

変数の型として、Boolean(ブール型)を多用しています。
ブール型は、True,Falseの2値をとる変数です。
つまり、ON,OFFや有,無等々の状態判定に使います。

判定に必要な項目の状態を、その項目ごとにTrue,Falseを先に判定し設定しておくことで、
その後に、複数の項目の状態を判定し、全体として条件を満たしているかどうかを判定しています。
これは、判定が複雑な場合に良く使う手法ですので、ぜひマスターして下さい。



「自分の石を置ける場所の判定の整理」
この文章と、VBAコードを見比べて下さい。
参考程度ではありますが、VBA内にコメントを書いておきました。

実際に、オセロ盤をダブルクリックして動作確認してみて下さい。
石の配置を変更する場合は、シート保護を解除してからコピペで石を配置してください。


今回は、文章をVBAコードにする部分に注力しました。
これで、オセロゲームの根本的な部分のロジックができましたので、
次回からは、ゲームとしての機能を一つずつ追加していきます。

№5へ続きます。
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第5回です。前回で石を置ける場所の判定が完成しましたので、これからは、ゲームとしての機能を一つずつ追加していきます。まずは、石を置ける場所の色を変更してわかりやすくしてみます。

全体の目次
はじめに
ExcelマクロVBAでオセロ(リバーシ)を作っていきながら、マクロVBAを学んで行きましょう。目的は、マクロVBAの学習であり、思考を整理しVBAでプログラミングする学習です。従って、強いソフトを作ることが目的ではありませんので、最近流行のAIなんちゃら…なんていうのは考えるつもりはありません。
№1.シートの用意と標準モジュールの挿入
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第1回です。まずはシートを用意しなければなりません、このシートの作り方で、その後の手間が随分と変わってきますので、しっかりと作ります。とはいえ、まずは一般的な感じで作ってみます、今後必要に応じて追加・変更していきます。
№2.ブックを開いたときの処理と初期配置
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第2回です。前回でシートの準備と標準モジュールを挿入しましたので、今回からは、マクロVBAをどんどん書き足していきます。まずは、イベントプロシージャーを作っていきます。
№3.自分の石を置ける場所の判定の整理
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第3回です。いよいよ自分の石を置いて、相手の石をひっくり返す処理に進むのですが、その前に、そもそも自分の石を置ける場所はどこなのか…。クリックしたセルは、自分の石を置いて良いセルなのかの判定が必要です。
№4.自分の石を置ける場所の判定の実装
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第4回です。石を置ける場所の定義を、前回は文章で書きました、今回は、それをもとにマクロVBAのプログラミングをしていきます。考え方は決定しているので、後はVBAに翻訳(コーディング)していくだけです。
№5.シート機能を拡張して今後の準備
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第5回です。前回で石を置ける場所の判定が完成しましたので、これからは、ゲームとしての機能を一つずつ追加していきます。まずは、石を置ける場所の色を変更してわかりやすくしてみます。
№6.黒石白石を交互に打って相手の石をひっくり返す
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第6回です。いよいよ今回は、黒石白石を交互に打てるようにします。もちろん、相手の石を挟んでいる場所は、自分の石に取り替えます。
№7.パス確認、終局確認、石数取得
VBAでオセロ(リバーシ)を作っていきながらVBAを学ぶ第7回です。前回までで、黒石白石を交互に打つことができるようになりましたが、まだまた不都合な点があります。石を打つ場所がない時に、パスが出来ないから先に進まない… 全部石が埋まっても、何も変化がない… そもそも、どっちが勝っているのかもわからない… つまり、
№8.石を置ける場所の表示とアニメーション
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第8回です。前回までで大分ゲームらしくなってきました。そろそろ、PC対戦の機能を入れたいところですが、今回は、はPC対戦の機能を入れる前に、気になる細かい部分を変更しておきます。
№9.PC対戦の実装
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第9回です。前回までで人が打つのであれば不自由のない機能が実装できたと思います。さて、ここからはPC対戦の機能を入れていきます。
№10.置く場所に重みを付けて少しだけ強く
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第10回です。前回は、PCが自動で打つ機能を実装しました。強さはともかく、とにかくPCが勝手に売ってくれるようになりました。
№11.相手の応手を評価してさらに強く
VBAでオセロ(リバーシ)を作っていきながらVBAを学ぶ第11回です。前回の石を置く場所に重みを付けることで、超々初心者なら勝てるかもしれないというレベルにはなりました。ですが、ある程度オセロをやった事のある人なら、まあ負けることはないでしょう 今回は、自分の打つ場所ではなく、
№12.PC対PCの対戦で強さを確認
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第12回です。前回は、相手の応手を判定して、自分の置く場所を決められるようにしました。オセロソフトとしては、そこそこの強さになりました。
№13.パラメーターと重みを調整してさらに強く
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第12回です。前回は、PC1からPC5までの5段階の状態で、総当り対戦で強さを判定しましたが、PC5が最も強い事が確認出来ました。それでもPC5では、まだまだ、ある程度オセロをやった事のある人には勝てないレベルです。
№14.やはり「待った」が欲しい
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第14回です。前回で、6段階の強さのPCオセロが完成しました、一番強いPC6でも、まだまだそれほどの強さとは言えませんが、初心者の人なら苦戦するでしょうし、私も油断すれば負けてしまうくらいの強さにはなっています。
№15.棋譜で対局を再現
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第15回です。棋譜が扱えるようになり、「待った」の実装も出来ました。棋譜が扱えるようになったので、今回は、対局を再現できるようにします。
№16.これまでを振り返りつつ全体のまとめ
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第16回です。15回に渡って、オセロ作成をしてきました、マクロVBAコードはかなりの量になっています。今回は最終回として、これまでを振り返ってみます。


ここまでのサンプルファイルのダウンロード




新着記事NEW ・・・新着記事一覧を見る

VBAでのCSVの扱い方まとめ|VBAサンプル集(11月9日)
VBAにおける変数のメモリアドレスについて|VBA技術解説(11月8日)
空文字列の扱い方と処理速度について(""とvbNullString)|VBA技術解説(1月7日)
Errオブジェクトとユーザー定義エラー|VBA入門(11月5日)
シングルクォートの削除とコピー(PrefixCharacter)|VBA技術解説(11月4日)
ユーザー定義型の制限とクラスとの使い分け|VBA技術解説(11月3日)
クリップボードに2次元配列を作成してシートに貼り付ける|VBA技術解説(11月1日)
VBAクラスを使ったイベント作成(Event,RaiseEvent,WithEvents)|VBA技術解説(10月31日)
VBAクラスのAttributeについて(既定メンバーとFor Each)|VBA技術解説(10月19日)
VBAの用語について:ステートメントとは|VBA技術解説(10月16日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数宣言のDimとデータ型|ExcelマクロVBA入門
6.繰り返し処理(For Next)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.ひらがな⇔カタカナの変換|エクセル基本操作
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.セルに文字を入れるとは(Range,Value)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。




    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
    本文下部へ