複数あるテキストボックスの入力漏れを確認する

先日、ユーザーフォームで作成した登録用フォームについて、複数あるテキストボックスの入力漏れを確認する事案があった。
f:id:Infoment:20181105205914p:plain

一か所でも登録漏れがあれば、未登録をお知らせして処理を中断させる。
f:id:Infoment:20181105211837p:plain
VBA覚えたての頃の私は、恐らくこんな感じ。

Private Sub CommandButton1_Click()
    If TextBox1.Value = "" Then
        MsgBox "TextBox1が未入力です。"
        Exit Sub
    ElseIf TextBox2.Value = "" Then
        MsgBox "TextBox2が未入力です。"
        Exit Sub
    ElseIf TextBox3.Value = "" Then
        MsgBox "TextBox3が未入力です。"
        Exit Sub
    ElseIf TextBox4.Value = "" Then
        MsgBox "TextBox4が未入力です。"
        Exit Sub
    ElseIf TextBox5.Value = "" Then
        MsgBox "TextBox5が未入力です。"
        Exit Sub
    End If
    
    Call 登録処理
End Sub

今見ても、別に駄目だとは思わない。全て空欄の場合、一つ埋めるごとに後出しで次のメッセージが出てくるが、それもまたよし。

少し時が経ち、繰り返し構文を覚えた頃なら、恐らくこんな感じ。

Private Sub CommandButton1_Click()
    Dim i As Integer
    For i = 1 To 5
        If Me.Controls("TextBox" & i).Value = "" Then
            MsgBox "TextBox" & i & " が未入力です。"
            Exit Sub
        End If
    Next
    
    Call 登録処理
End Sub

前よりも随分スッキリしている。テキストボックス数に増減があれば「5」の部分に改修を要するが、これでも充分用をなしている。

今だったら、どうするだろう。面倒くさがりな私は、とにかく空欄があることだけを伝えるかもしれない。

Private Sub CommandButton1_Click()
    If CheckBlank = True Then
        MsgBox "空欄が残っています。"
        Exit Sub
    Else
        登録処理
    End If
End Sub

Function CheckBlank() As Boolean
    Dim myControl As Control
        For Each myControl In Controls
            If TypeName(myControl) = "TextBox" Then
                If myControl.Value = "" Then
                    CheckBlank = True
                    Exit Function
                End If
            End If
        Next
        CheckBlank = False
End Function

昔より長いコードになってしまった。でも、テキストボックスの増減に自動で追従する分だけ、変化に強いコードになったと思う。

或いは、こんな感じだろうか。

  1. 空欄のテキストボックスを示すエラーメッセージ作成。
  2. 「メッセージがあれば空欄あり」のフラグ作成。
  3. 上記フラグで条件分岐。
Private Property Get ErrMsg() As String
    Dim seq As Variant
    Dim i As Long
        i = 1
    ReDim seq(i)
    Dim myControl As Control
        For Each myControl In Controls
            If TypeName(myControl) = "TextBox" Then
                If myControl.Value = "" Then
                    seq(i) = "・" & myControl.Name
                    i = i + 1
                    ReDim Preserve seq(i)
                End If
            End If
        Next
        
        If i = 1 Then
            ErrMsg = ""
        Else
            seq(0) = "以下のテキストボックスが空欄です。"
            seq(i) = "処理を中断します。"
            ErrMsg = Join(seq, vbNewLine)
        End If
End Property
Private Property Get CheckBlank() As Boolean
    Select Case ErrMsg
        Case ""
            CheckBlank = False
        Case Else
            CheckBlank = True
    End Select
End Property
Private Sub CommandButton1_Click()
    If CheckBlank = True Then
        MsgBox ErrMsg
        Exit Sub
    Else
        Call 登録処理
    End If
End Sub

ここまで来ると、初期の面影は全くない。
f:id:Infoment:20181105215533g:plain

思い付きで作ったので、「凝りすぎ」「この使い方はNG」と言われるかもしれない。でも正直、1ヵ月前ならこの発想は生まれなかったと思う(この1ヵ月で、前より少し成長したと思われ)。ということは更に1ヵ月後、全く違うコードを書いているかもしれない。その点については、少し楽しみでもある。

・・・あるいは、袋小路にはまり込んで、ジタバタしているかもしれません。

参考まで。