条件付き有限ループ


タイトルを悩んだのですけど、要するに次のような動作です。マクロ中で、ユーザーにパスワードなどを入れてもらうとき、

ここで正しいパスワードを入力してくれればいいのですが、間違えるときもありますよね。そんなときは、

のようなメッセージを出して、再び

の画面を出して、また入力させたい。正しいパスワードが入力されない限り、これを繰り返したいと。とはいえ、これを延々と無限に繰り返していては、マクロ作成者も、そのマクロを使っている人も、どちらも気まずくなって人間関係に影響が出るかもしれません。なので、適当なところで

みたいなメッセージを出して、処理を中止してしまおうと。そういう仕組みです。これ、けっこう多くの方が作れなくて困っているようですね。

まず、InputBoxを出して、間違ったパスワードだったらメッセージを出すところです。なお、ここでは正しいパスワードを"1234"としました。安易ですみません。

Sub Macro1()
    Dim A As String
    A = InputBox("パスワードを入力してください")
    If A <> "1234" Then
        MsgBox "パスワードが違います", vbExclamation
    End If
End Sub

ここで「もしパスワードが間違っていたら、InputBoxの行に戻りたい(ジャンプしたい)」と考えてはいけません。「正しいパスワードが入力されるまで、InputBoxを繰り返したい」と考えます。これ、まったく意味が違いますよ。繰り返すのですから、これをDo Loopで囲みます。

Sub Macro1()
    Dim A As String
    Do
        A = InputBox("パスワードを入力してください")
        If A <> "1234" Then
            MsgBox "パスワードが違います", vbExclamation
        End If
    Loop
End Sub

じゃ、正しいパスワードが入力されたかどうか、どうやって判定すればいいのでしょう。簡単です、それようの変数をひとつ使えばいいんです。一般的に、こうした目的で使う変数のことをフラグなどと呼びます。

Sub Macro1()
    Dim A As String, flag As Boolean
    Do While flag = False
        A = InputBox("パスワードを入力してください")
        If A <> "1234" Then
            MsgBox "パスワードが違います", vbExclamation
        Else
            flag = True
        End If
    Loop
End Sub

落ち着いて考えてくださいね。ブール型の変数flagは、最初(初期値が)Falseです。もし、正しいパスワードが入力されたときだけ、この変数flagにTrueをセットします。ということは、正しいパスワードが入力されない限り、永遠に変数flagはFalseのままです。Do Loopの条件には「もし、変数flagがFalseだったら繰り返す」を指定しています。したがって、正しいパスワードが入力されない限り、このDo Loopは永遠に繰り返されます。

間違ったパスワードが"5回"入力されたかの判定も、間違えた回数をカウントする変数を用意します。

Sub Macro1()
    Dim A As String, flag As Boolean, N As Long
    Do While flag = False
        A = InputBox("パスワードを入力してください")
        If A <> "1234" Then
            MsgBox "パスワードが違います", vbExclamation
            N = N + 1
        Else
            flag = True
        End If
    Loop
End Sub

これで、パスワードを間違えるたびに、変数Nが1ずつ増えていきます。この変数Nが4のとき、さらに間違えたら、それは5回目の間違いです。そこで、処理を中止すればいいです。

Sub Macro1()
    Dim A As String, flag As Boolean, N As Long
    Do While flag = False
        A = InputBox("パスワードを入力してください")
        If A <> "1234" Then
            If N = 4 Then
                MsgBox "5回間違えたので処理を中止します", vbExclamation
                Exit Sub
            Else
                MsgBox "パスワードが違います", vbExclamation
                N = N + 1
            End If
        Else
            flag = True
        End If
    Loop
End Sub