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

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へ続きます。

全体の目次


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




同じテーマ「マクロVBAサンプル集」の記事

エクセルでファイル一覧を作成
アメブロの記事本文をVBAでバックアップする№6
数独(ナンプレ)を解くVBAに挑戦№5
数独(ナンプレ)を解くアルゴリズムの要点とパフォーマンスの検証№4
ナンバーリンク(パズル)を解くVBAに挑戦№8
ナンバーリンクを解くVBAのパフォーマンス改善№3
オセロを作りながらマクロVBAを学ぼう№9
他ブックへのリンクエラーを探し解除するマクロ(変更前)
Excelシートの複雑な計算式を解析するVBAの関数構文


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

Applicationを省略できるApplicationのメソッド・プロパティ一覧|VBA技術解説(7月22日)
コレクション(Collection)の並べ替え(Sort)に対応するクラス|VBA技術解説(7月20日)
CSVの読み込み方法(ジャグ配列)|VBAサンプル集(7月15日)
その他のExcel機能(グループ化、重複の削除、オートフィル等)|VBA入門(7月14日)
オートフィルタ退避回復クラスを複数シート対応させるVBAクラス|VBA技術解説(7月6日)
オートフィルタを退避回復するVBAクラス|VBA技術解説(7月6日)
IfステートメントとIIF関数とMax関数の速度比較|VBA技術解説(6月23日)
Withステートメントの実行速度と注意点|VBA技術解説(6月6日)
VBA+SeleniumBasicで検索順位チェッカー(改)|VBA技術解説(6月2日)
マクロでShift_JIS文字コードか判定する|VBA技術解説(6月1日)


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

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



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

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


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




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