Excelマクロ・VBA 初心者向け練習問題1 じゃんけんゲーム

2022年10月18日

マクロ・VBAを練習する課題として、じゃんけんゲームを紹介します。

筆者がプログラミングの専門学校で、実際に学んだ物の例題でもあります。

(ソースなどゼロから作成してあります)

マクロ・VBAやプログラミングの重要要素である変数と判断(IF)の学習に最適な課題です。

ソースコードを紹介するため是非、作成することをお勧めします。

なおコピー&ペーストでなく意味を考えながらタイピングすると学習効果が高いです。

サンプルファイル

ゲーム内容

※セキュリティの警告が出る場合は有効化してください。(解除方法↓)

グー、チョキ、パーの手のボタンがあり何れかを押すとコンピュータと勝負します。

じゃんけんゲームの画面
じゃんけんゲームの画面
勝負の結果
勝負の結果

勝負の結果は上の表にカウントされていきます。

勝負の結果は上の表にカウント

この結果は「勝敗リセット」ボタンで全てが0に戻ります。

コード

Option Explicit

'定数設定
Const グー As Integer = 1
Const チョキ As Integer = 2
Const パー As Integer = 3
Const 勝ち数セル As String = "D3"
Const 負け数セル As String = "G3"
Const あいこ数セル As String = "J3"

Function 手の定数を手の名前に変換(手) As String
    
    If 手 = グー Then
        手の定数を手の名前に変換 = "グー"
    ElseIf 手 = チョキ Then
        手の定数を手の名前に変換 = "チョキ"
    ElseIf 手 = パー Then
        手の定数を手の名前に変換 = "パー"
    End If
    
End Function

Sub グーボタン()
    Call ゲーム開始(グー)
End Sub

Sub チョキボタン()
    Call ゲーム開始(チョキ)
End Sub

Sub パーボタン()
    Call ゲーム開始(パー)
End Sub

Function ゲーム開始(プレイヤーの手 As Integer)

    Dim コンピュータの手 As Integer
    Dim メッセージ As String
    
    コンピュータの手 = コンピュータが手を選ぶ()

    If プレイヤーの手 = グー Then
    
        If コンピュータの手 = グー Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        End If
    End If

    If プレイヤーの手 = チョキ Then
        
        If コンピュータの手 = グー Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        End If
    End If
    
    If プレイヤーの手 = パー Then
        
        If コンピュータの手 = グー Then
            メッセージ = "プレイヤーの勝ちです。"
            Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
            
        ElseIf コンピュータの手 = チョキ Then
            メッセージ = "プレイヤーの負けです。"
            Range(負け数セル).Value = Range(負け数セル).Value + 1
            
        ElseIf コンピュータの手 = パー Then
            メッセージ = "あいこです。"
            Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
            
        End If
    End If
    
    MsgBox (メッセージ + "プレイヤー:" + 手の定数を手の名前に変換(プレイヤーの手) + "。コンピューター:" + 手の定数を手の名前に変換(コンピュータの手))

End Function

Function コンピュータが手を選ぶ() As Integer
    Randomize   '乱数系列初期化。ランダムの数字を使うために必要
    コンピュータが手を選ぶ = Int(3 * Rnd() + 1) '1~3のランダム
End Function

Sub 勝敗リセット()
    Range(勝ち数セル).Value = 0
    Range(負け数セル).Value = 0
    Range(あいこ数セル).Value = 0
End Sub

解説

Option Explicit

Dimによる変数宣言をしないと変数を使えないようにする設定です。

(プログラミングにおける変数はデータを格納する箱に

 名前を付けたものと認識するのが一般的です)

宣言していない変数を使用すると構文エラーとなりプログラムが動かなくなります。

一見、不便に感じますが実際には作成効率が良くなります。

変数名を間違えて打ち込んでしまった際、

この設定をしていれば構文エラーで検出が出来ますが、

そうでない場合、新しい空の変数となってしまいプログラムの挙動がおかしくなります。

よって初心者の方ほどOption Explicitを設定することを推奨します。

定数設定

定数とは最初に値を設定して以降、プログラム中で変更しない変数です。

セルのアドレスなどプログラム中で多用するものを設定します。

定数にするとプログラム中で間違えて中身を変えることを防ぐことが出来ます。

またシートの内容を変更してセルの場所が変わった場合、

定数にしておくと定数の宣言文だけ替えればよいですが、

そうでない場合、アドレスの使用箇所を全て変える必要が発生し、

手間と間違える危険性が発生します。

変数定数
宣言DimConst
値の変更プログラム中のどこでも可能宣言時のみ可能

Asはデータ型(データの種類)の宣言です。

Integerは整数、Stringが文字列です。他にも多数あります。

'定数設定
Const グー As Integer = 1
Const チョキ As Integer = 2
Const パー As Integer = 3
Const 勝ち数セル As String = "D3"
Const 負け数セル As String = "G3"
Const あいこ数セル As String = "J3"

手の定数を手の名前に変換Function

Functionはプロシージャの一つでコードを一まとめにして名前を付ける機能です。

他の言語では関数やメソッド、サブプログラムなど様々な呼び方があります。

何度も使用するコードや長いコード、シートから呼び出す場合に使用します。

プロシージャにはFunctionとSubがあります。

Function
(ファンクション)
Sub
(サブ)
戻り値(結果)返す返さない
セルの数式から
ユーザ定義関数として実行
可能不可能
ボタンなどの
オブジェクトから実行
不可能可能

手の定数を手の名前に変換Functionは先述の定数で定義した数値の手を

人間にわかる表現にするFunctionです。

プロシージャにする必要性は低いのですがテストしやすくするためにFunctionにしています。

Function 手の定数を手の名前に変換(手) As String
If 手 = グー Then
        手の定数を手の名前に変換 = "グー"
    ElseIf 手 = チョキ Then
        手の定数を手の名前に変換 = "チョキ"
    ElseIf 手 = パー Then
        手の定数を手の名前に変換 = "パー"
    End If
End Function

Functionであればセルの数式でユーザ定義関数として実行できます。

手の定数を手の名前に変換Functionの実行例
手の定数を手の名前に変換Functionの実行例

Functionは下記のように作成します。

黄色のマーカーの箇所は作成者が自由に決める部分です。

Function ファンクション名(引数) As データ型
ファンクション名 = 戻り値
End Function 

ファンクション名や引数名は可能な限りファンクションや引数の役割を表す名前にしましょう。

ファンクション名に値を入れると入れた値が戻り値となります。

(多くの言語ではreturn句が多いです)

引数やデータ型は省略可能です。

手のボタンSub

シート上のボタンから呼び出すためのプロシージャです。

それぞれ対応する手を引数にゲーム開始Functionを実行します。

戻り値のないプロシージャを実行する場合はCallを使用します。

Sub グーボタン()
    Call ゲーム開始(グー)
End Sub

Sub チョキボタン()
    Call ゲーム開始(チョキ)
End Sub
Sub パーボタン()
    Call ゲーム開始(パー)
End Sub

作成したらボタンからマクロの登録を行います。

Subを呼び出すボタン
Subを呼び出すボタン

ゲーム開始Function

Function宣言

Function ゲーム開始(プレイヤーの手 As Integer) 

引数として「プレイヤーの手」を受けます。

前述の手のボタンSubから呼び出されプレイヤーの手に1(グー)か

2(チョキ)か3(パー)が引数として格納されます。

IF文による勝敗判定

「プレイヤーによる手」ごとに勝敗判定のIF文を作ります。

下記はグーを選ぶ場合のIFです。

If プレイヤーの手 = グー Then
If コンピュータの手 = グー Then
        メッセージ = "あいこです。"
        Range(あいこ数セル).Value = Range(あいこ数セル).Value + 1
        
    ElseIf コンピュータの手 = チョキ Then
        メッセージ = "プレイヤーの勝ちです。"
        Range(勝ち数セル).Value = Range(勝ち数セル).Value + 1
        
    ElseIf コンピュータの手 = パー Then
        メッセージ = "プレイヤーの負けです。"
        Range(負け数セル).Value = Range(負け数セル).Value + 1
        
    End If
End If

一番、上位のIFで「プレイヤーの手」の判定をして、

その中のIFで「コンピュータの手」と突き合わせます。

「プレイヤーの手」と「コンピュータの手」をで一致するパターンがあれば

表示するメッセージ設定と勝敗セルへの値設定を行います。

この構文は指定セルの値を1つカウントアップする構文です。

Range(セルアドレス).Value = Range(セルアドレス).Value + 1

同様のIF文の入れ子をチョキとパーのバージョンで作り

MsgBoxで結果をプレイヤーに提示します。

コンピュータが手を選ぶFunction

Function コンピュータが手を選ぶ() As Integer
    Randomize   '乱数系列初期化。ランダムの数字を使うために必要
    コンピュータが手を選ぶ = Int(3 * Rnd() + 1) '1~3のランダム
End Function

1,2,3の値をランダム(乱数)で返すFunctionです。

「Randomize」は乱数を使うために必要な構文です。

Rnd()は0~0.999...のうち何れかの値を返します。

これに3を掛けることで0~2.999...の何れかになります。

そこに1を足すと1~3.999...になります。

Intは小数点以下を切り捨てて整数にするFunctionです。

これにより1か2か3になります。

勝敗リセットSub

Sub 勝敗リセット()
    Range(勝ち数セル).Value = 0
    Range(負け数セル).Value = 0
    Range(あいこ数セル).Value = 0
End Sub

Subプロシージャのためボタンから呼び出す処理です。

このSubは勝敗リセットボタンにマクロ登録をします。

勝敗リセットボタンにマクロ登録
Range(セルアドレス).Value = 値

はセルに値を設定するコードです。

逆に書くとセルから値を取得するコードになります。

変数 = Range(セルアドレス).Value

関連記事

マクロ・VBAの学習・活用方法の記事一覧