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

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

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


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


前回は、PC1からPC5までの5段階の状態で、総当り対戦で強さを判定しましたが、
PC5が最も強い事が確認出来ました。

それでもPC5では、まだまだ、ある程度オセロをやった事のある人には勝てないレベルです。
もう少し強くするために、以下の機能を追加します。

・「重み」の数値を中盤から変更する。
・自分がひっくり返す相手石の数。
・自分がひっくり返す相手石の場所の重み。
・辺で自分の石が全て連続になる場合は、それを優先する。


これらの機能を追加して、「PC6」として作成します。
この機能を考えたのは、実際に自分でPC5を相手にしてやってみたときに、
あっ、そこに置いたんじゃ勝てないよ・・・
と思うような場所に置いてしまう事が多々ありました。
そのような手をを減らす為に、何を判定するかを考えた結果が上記の機能になります。


Workbook_OpenイベントにPC6を追加


Private Sub Workbook_Open()
  With Sheet1
    .Select
    .Unprotect
    .Cells.Locked = True
    .ScrollArea = "B2:I9"
    With .cmb1
      .Clear
      .AddItem "あなた"
      .AddItem "PC1"
      .AddItem "PC2"
      .AddItem "PC3"
      .AddItem "PC4"
      .AddItem "PC5"
      .AddItem "PC6"
    End With
    With .cmb2
      .Clear
      .AddItem "あなた"
      .AddItem "PC1"
      .AddItem "PC2"
      .AddItem "PC3"
      .AddItem "PC4"
      .AddItem "PC5"
      .AddItem "PC6"
    End With
    .Protect
  End With
End Sub



「重み」の数値を中盤から変更する。
シート「重み」、このシート名を変更できるように、
プロシージャーレベルのPublic変数を定義します。

Option Explicit

Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public TargetSheet As Worksheet
Public 置く石 As Range
Public 相手石 As Range
Public isPCvsPC As Boolean
Public StopMsg As Boolean
Public sht重み As String

「対戦開始」
ここで、初期配置の直前あたりで、
sht重み = "重み"
このようにして、シート名を入れます。
後は、
Worksheets("重み")

Worksheets(sht重み)
このように一括置換します。



自分がひっくり返す相手石の数。
自分が石を置いて相手の石をひっくり返す石を数えます。



Function 次手シミュ5(ByVal myRng As Range) As Long
  Dim rng1 As Range
  Dim r As Long
  Dim c As Long
  Dim cnt As Long
  
  arySim2 = arySim
  Set rng1 = TargetSheet.Range("盤面")
  
  r = myRng.Row - rng1.Row + 1
  c = myRng.Column - rng1.Column + 1
  
  '自分がひっくり返す相手石の数
  cnt = is置ける全方向S(r, c, "1")
  次手シミュ5 = cnt
End Function

他の、次手シミュ○とほぼ同様の内容になっています。
このような判定であれば、コピペで簡単につくれるようになっています。



自分がひっくり返す相手石の場所の重み。
自分がひっくり返す相手石の場所の重みの最小値を取得します。

下図のような場合に、結構安易に「ダメ」に打っているようだったので、
これを個別判定して回避するようにします。

マクロVBAサンプル画像

Function getOwnWait(ByVal myRng As Range) As Long
  Dim rng1 As Range
  Dim i As Long
  Dim j As Long
  Dim r As Long
  Dim c As Long
  Dim rtn As Long
  
  getOwnWait = 999
  arySim2 = arySim
  Set rng1 = TargetSheet.Range("盤面")
  
  r = myRng.Row - rng1.Row + 1
  c = myRng.Column - rng1.Column + 1
  
  '自分がひっくり返す相手石の場所の重み
  For i = 1 To 8
    For j = 1 To 8
      rtn = is置ける全方向S(i, j, "1", "最小")
      If getOwnWait > rtn Then
        getOwnWait = rtn
      End If
    Next
  Next
End Function

次手シミュ○とほぼ同様の作りになっています。
プロシージャーを、次手シミュ○にしなかったのは、
判定に使うのが、角の取り合いのみにしか使和ないからです。
従って、実際には、その重みが-15の場合限定で使用します。



辺で自分の石が全て連続になる場合は、それを優先する。
辺での石の取り合いを放棄することが多かったので、
他の要素に置いて、特別な理由がない限り、辺は確保するようにします。

マクロVBAサンプル画像

このような場合は、素直に白石を取るようにします。
しかし、

マクロVBAサンプル画像

このように、白石を取った後に、まだ白石が残るような場合は、
この白石を取ったほうが良いのか、撮らない方が良いのかは、
他の部分との兼ね合いで、全体を判断しなければ分からないので、
ここでの追加機能では、取る判定にはしないようにします。

Function isSide(ByVal myRng As Range) As Boolean
  Dim rng1 As Range
  Dim i As Long
  Dim j As Long
  Dim r As Long
  Dim c As Long
  Dim flg As Integer
  Dim cnt As Long
  
  isSide = False
  arySim2 = arySim
  Set rng1 = TargetSheet.Range("盤面")
  
  r = myRng.Row - rng1.Row + 1
  c = myRng.Column - rng1.Column + 1
  Call is置ける全方向S(r, c, "1")
  
  If r = 1 And (c = 1 Or c = 8) Then Exit Function
  If r = 8 And (c = 1 Or c = 8) Then Exit Function
  If r <> 1 And r <> 8 And c <> 1 And c <> 8 Then Exit Function
  
  cnt = 0
  '辺で自分の石が全て連続になる場合は、それを優先する
  Select Case True
    Case r = 1 Or r = 8
      flg = 0
      For i = 1 To 8
        If arySim2(r, i) = "" Then
          If flg = 1 Then
            flg = 2
          End If
        End If
        If arySim2(r, i) <> "" Then
          If flg = 2 Then
            Exit Function
          End If
          If arySim2(r, i) = "2" Then
            Exit Function
          End If
          flg = 1
          cnt = cnt + 1
        End If
      Next
    Case c = 1 Or c = 8
      flg = 0
      For i = 1 To 8
        If arySim2(i, c) = "" Then
          If flg = 1 Then
            flg = 2
          End If
        End If
        If arySim2(i, c) <> "" Then
          If flg = 2 Then
            Exit Function
          End If
          If arySim2(i, c) = "2" Then
            Exit Function
          End If
          flg = 1
          cnt = cnt + 1
        End If
      Next
  End Select
  If cnt > 1 Then
    isSide = True
  End If
End Function

完全に、新規ロジックになっています。
縦の辺と、横の辺で分かれています。
自分の石を置いて、相手の石をひっ繰返した後に、辺の状態を確認しています。
行方向と列方向で違いますので、Ifで分けています。

flg
これで制御しています。
0:初期
1:何らかの石が出てきた
2:空白以外が出た後に、空白が出てきた。
相手の石が出てきたら、即終了しています。
結果として、辺の状態が自分の石だけになっていれば優先扱いするようにしています。



次着手にPC6を追加
次手着手に上記で作成したものを組み込みます。

Function 次手候補() As Range
  Dim ix As Long
  Dim ix2 As Long
  Dim myRng As Range
  Dim aryRng() As Range
  Dim aryRng2() As Range
  Dim aryWait() As tWait
  Dim maxWait(1 To 5) As Long
  Dim maxWaitT As Long
  Dim cnt As Long
  Dim PcName As String
  
  For ix = 1 To 5
    maxWait(ix) = -999
  Next
  maxWaitT = -999
  With TargetSheet
    If .Range("手番石").Font.Color = .Range("先番石").Font.Color Then
      PcName = Sheet1.cmb1.Text
    Else
      PcName = Sheet1.cmb2.Text
    End If
    cnt = WorksheetFunction.CountA(.Range("盤面"))
    ix = 0
    Call 盤面配列化
    For Each myRng In .Range("盤面")
      If is置ける全方向(myRng, True) Then
        ReDim Preserve aryRng(ix)
        ReDim Preserve aryWait(ix)
        Set aryRng(ix) = myRng
        aryWait(ix).wait1 = 次手シミュ1(myRng)    '自分の置く石の重み
        aryWait(ix).wait2 = 100 - 次手シミュ2(myRng) '相手が置ける場所数
        aryWait(ix).wait3 = 100 - 次手シミュ3(myRng) '相手が置ける石の重み
        aryWait(ix).wait4 = 100 - 次手シミュ4(myRng) '相手がひっくり返す数
        aryWait(ix).wait5 = 次手シミュ5(myRng) '自分がひっくり返す相手石の数
        If PcName = "PC6" Then
          '辺で自分の石が全て連続になる場合は、それを優先する
          If isSide(myRng) And aryWait(ix).wait1 <> -12 Then
            aryWait(ix).wait1 = 1
          End If
          '自分がひっくり返す相手石の場所の重み
          If aryWait(ix).wait1 <> 30 And getOwnWait(myRng) = -15 Then
            aryWait(ix).wait1 = -15
          End If
        End If
        ix = ix + 1
      End If

    Next
    For ix = LBound(aryWait) To UBound(aryWait)
      If maxWait(1) < aryWait(ix).wait1 Then maxWait(1) = aryWait(ix).wait1
      If maxWait(2) < aryWait(ix).wait2 Then maxWait(2) = aryWait(ix).wait2
      If maxWait(3) < aryWait(ix).wait3 Then maxWait(3) = aryWait(ix).wait3
      If maxWait(4) < aryWait(ix).wait4 Then maxWait(4) = aryWait(ix).wait4
      If maxWait(5) < aryWait(ix).wait5 Then maxWait(5) = aryWait(ix).wait5
    Next
    
    For ix = LBound(aryWait) To UBound(aryWait)
      Select Case PcName
        Case "PC1"

        Case "PC2"
          If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
        Case "PC3"
          If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
          If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
        Case "PC4"
          Select Case cnt
            Case Is <= 32
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 1
            Case Is <= 48
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 1
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 3
            Case Is <= 52
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 4
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 2
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 4
            Case Is <= 56
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 2
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 3
            Case Else
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 2
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 4
          End Select
        Case "PC5"
          Select Case cnt
            Case Is <= 32
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 1
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
            Case Is <= 48
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 1
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 3
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
            Case Is <= 52
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 3
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 1
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 5
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
            Case Is <= 56
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 1
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 5
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
            Case Else
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 1
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 0
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 3
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 5
          End Select
        Case "PC6"
          If cnt >= 27 Then
            sht重み = "重み2"
          End If
          Select Case cnt
            Case Is <= 32
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 1
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
              If aryWait(ix).wait5 = maxWait(5) Then aryWait(ix).wait5n = 0
            Case Is <= 48
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 5
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 1
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 3
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
              If aryWait(ix).wait5 = maxWait(5) Then aryWait(ix).wait5n = 0
            Case Is <= 52
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 3
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 1
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 5
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
              If aryWait(ix).wait5 = maxWait(5) Then aryWait(ix).wait5n = 0
            Case Is <= 56
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 1
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 3
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 5
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 0
              If aryWait(ix).wait5 = maxWait(5) Then aryWait(ix).wait5n = 0
            Case Else
              If aryWait(ix).wait1 = maxWait(1) Then aryWait(ix).wait1n = 2
              If aryWait(ix).wait2 = maxWait(2) Then aryWait(ix).wait2n = 2
              If aryWait(ix).wait3 = maxWait(3) Then aryWait(ix).wait3n = 2
              If aryWait(ix).wait4 = maxWait(4) Then aryWait(ix).wait4n = 5
              If aryWait(ix).wait5 = maxWait(5) Then aryWait(ix).wait5n = 5
          End Select

      End Select
      aryWait(ix).wait9n = aryWait(ix).wait1n + _
                  aryWait(ix).wait2n + _
                  aryWait(ix).wait3n + _
                  aryWait(ix).wait4n + _
                  aryWait(ix).wait5n
      If maxWaitT < aryWait(ix).wait9n Then
        maxWaitT = aryWait(ix).wait9n
      End If
    Next
    
    ix2 = 0
    For ix = 0 To UBound(aryRng)
      If aryWait(ix).wait9n = maxWaitT Then
        ReDim Preserve aryRng2(ix2)
        Set aryRng2(ix2) = aryRng(ix)
        ix2 = ix2 + 1
      End If
    Next
    
    Randomize
    ix = Int(Rnd * (UBound(aryRng2) + 1))
    Set 次手候補 = aryRng2(ix)
  End With
End Function

判定結果のポイント化においても、その比重を調整しています。
そして、新規に追加した機能も全て組み込んでいます。



実際に戦わせた結果
100戦ずつ戦わせた結果です。

マクロVBAサンプル画像

左が先手、上が後手
上段が先手勝ち、下段が後手勝ちです。

予定通りではありますが、
PC6が完全に勝ちました。
もちろん、勝つように調整したのですけど。



今回の実装で、かなり強くなりました。
私も油断すると負けてしまいます。
それでも、しっかり考えながら打てば、まだ負けません。
ですが、本当の初心者だと、とても勝てないレベルになっています。

私が打つときは、序盤は全体の形だけを気にして打ちますが、
中盤から終盤にかけては、
自分が打つ→相手が打つ→自分が打つ
このあたりまでは考えながら打ちます。
時には、さらに相手が打つときも少しは考えます。

今回のソフトでは、
自分が打つ→相手が打つ
ここまでしか判定していませんので、
私かじっくり考えながら打たば勝てるのは当然の結果だと思います。
それでも、判定結果をポイント化する時をいろいろシミューションしていけば、
もう少しは強くすることが出来るとは思います。

ですが、私に完全に勝てるソフトにするには、
3手先以上を読まなければなりません。
それには、「ゲーム木」の考えを入れて、
3手先以上を読めるようにしなければならないと思います。
ですが、そこまでやって強くしても、本記事の主旨にはそぐわないし、
そもそも、強いソフトをつくる事が目的ならVBAじゃなくても良いわけですし。

さて、オセロソフトとしては、ほぼ当初の予定を完了しました。
それなりの強さにもなりました。

次回は、自分で遊ぶとき用に、便利機能を追加しようと思います。
そう、「待った」をしたいですよね。
VBAに負けるのは、さすがに気分が悪い(笑)


№14へ続きます。
ExcelマクロVBAでオセロ(リバーシ)を作っていきながらマクロVBAを学ぶ第14回です。前回で、6段階の強さのPCオセロが完成しました、一番強いPC6でも、まだまだそれほどの強さとは言えませんが、初心者の人なら苦戦するでしょうし、私も油断すれば負けてしまうくらいの強さにはなっています。

全体の目次
はじめに
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」をお願いいたします。
    本文下部へ