【Excel VBA】ユーザーフォームの入力漏れ防止について

記事
IT・テクノロジー

YouTubeでも紹介しています。 是日 ご覧ください


データベースを作成するにあたり、入力漏れは大敵です。
今回は、ACCESSではなく、Excelのユーザーフォームについて2つの考えたでアプローチしたいと思います。


ユーザーフォームの入力漏れ防止について

こんにちは。伊川です。
ユーザーフォームで入力漏れを防止するには、様々は方法があります。
テキストボックス1個毎に設定するのは、結構大変です。
テキストボックスが、100個あったら、100個の処理を書く必要があります。
以前の私は、このようなことをしていました。
しかし、とてつもなく、非効率です。
そして、Functionを利用して、一括で、入力漏れを防止していました。
この考え方は、For~Eachを利用して、一括管理します。
しかし、発想を変えると、もっと便利になるかもしれません。

このブログは、こんな人にお勧め

Excelのユーザーフォームで入力漏れを防止したい人
Functionを勉強している人
クラスモジュールを勉強している人

このブログを読み終わるころには・・・・・


今回の内容は、入門レベルでは決して足りない実務に必須のスキルとは ExcelVBAの11章で紹介されている内容です。
書籍では、クラスモジュールを利用して記載はされていません。
しかし、クラスモジュールを利用すると、すごく、コードが短くなります。


入力漏れの考え方


今まで、私は、Functionを利用して入力漏れを、防止していました。
しかし、その入力漏れを、すり抜けてくる輩がいます。
現時点では、これが最強と思っていました。
しかし、入門レベルでは決して足りない実務に必須のスキルとは ExcelVBAの11章で
私が感銘する内容でしたので、紹介しようと思います。


入力漏れ防止 作業手順 その1 Functionで入力漏れ防止


ACCESSで紹介しましたが、今回はExcelで実行します。
コードは、ほとんど変わりません。

1.jpg

名前、年齢、電話番号に、入力漏れがあったら、登録させないというモノです。

1.jpg

このようにエラーがでます。
しかし、どんなに、入力漏れ防止をしても、すり抜けてくる輩がいます。
Functionのコードは下記の通りです。
標準モジュールに下記のコードを記載します。
Public Function 入力漏れ() As Boolean
 Dim myCtrl As Control
  For Each myCtrl In UserForm2.Controls
        If myCtrl.Name Like "txt*" Then
         If IsNull(myCtrl.Value) Or (myCtrl.Value = "") Then
            MsgBox "入力必須項目に入力漏れがあります"
            入力漏れ = True
            Exit Function
         End If
        End If
    Next
  入力漏れ = False
End Function
フォームモジュールに下記のコードを記載します。
Private Sub CommandButton1_Click()
 If Module1.入力漏れ Then Exit Sub
   maxrow = Cells(Rows.Count, "A").End(xlUp).Row + 1
     For i = 1 To 3
       Cells(maxrow, i) = UserForm2.Controls("txtTextBox" & i).Value
      Next i
 Unload UserForm2
End Sub
下記のコードに関しては、ユーザーフォームでを、×閉じさせないコードです。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        MsgBox "[登録]ボタンを使用してください"
        Cancel = True
    End If
End Sub


入力漏れ防止 作業手順 その2 クラスモジュールで入力漏れ防止


1.jpg



ユーザーフォームを起動すると、登録ボタンが、グレーアウトになっています。

1.jpg


テキストボックスに、全て、値が埋まったら、グレーアウトが解除され、登録ボタンを、押せるようになります。
この考え方は素晴らしいです。
しかし、Functionで実行するよりも、各段に難しく、3日考えても分かりませんでした。


入力漏れ防止 作業手順 その3 クラスモジュールの考え方


1.jpg


ユーザーフォームには、Changeというイベントがあります。
テキストボックスの値が、変わったら、何かのイベントを発生させるというモノです。
つまり、テキストボックスの内容が変わり、かつ、テキストボックスの内容が、Nullまたは、空ではなかったら、
登録ボタンを有効にさせるという事です。
このテキストボックスが、Changeした時に、毎回、判定をすることになります。


しかし、今回は、テキストボックスが、3つしかないので、問題はありません。
もし、テキストボックスが、100個あった場合、100個の処理を書くのかという問題に直面します。
その時に、利用するのが、クラスモジュールです。


テキストボックスのChangeイベントが発生するという、このイベントを、クラスモジュールで一括管理します。
ここが、分かりませんでした。
テキストボックス毎に処理をするのがイヤだったので、3日考えましたがダメでした。
なので、某掲示板で教えていただきました。
クラスモジュールは、ネットで探しても、サンプルが少ないので、皆さまのお役に立てれば幸いです。

入力漏れ防止 作業手順 その4 クラスモジュールのコード


クラスモジュールに下記のコードを記載します。
クラスは、Class1とします。
Option Explicit
'複数イベントを1つにまとめる
Private WithEvents TextEv As MSForms.TextBox
Public Sub NewClass(ByVal Tbox As MSForms.TextBox)
    'コンストラクタ処理
    Set TextEv = Tbox
End Sub
Private Sub TextEv_Change()
    Call CB1Enable
End Sub
標準モジュールに下記のコードを記載します。
Public Sub CB1Enable()
    UserForm1.CB1.Enabled = 入力漏れ無
End Sub
Public Function 入力漏れ無() As Boolean
    Dim myCtrl As Control
    入力漏れ無 = True
    For Each myCtrl In UserForm1.Controls
        If myCtrl.Name Like "txt*" Then
            If Len(myCtrl.Value) = 0 Then
                入力漏れ無 = False
                Exit Function
            End If
        End If
    Next
End Function
フォームモジュールに下記のコードを記載します。
Private NumText(1 To 3) As New Class1
Private Sub UserForm_Initialize()
     CB1.Enabled = False
    'インスタンスの生成
    Dim i As Long
    For i = 1 To 3
        NumText(i).NewClass Controls("txtTextBox" & i)
    Next
End Sub
Private Sub CB1_Click()
 If Module1.入力漏れ Then Exit Sub
   maxrow = Cells(Rows.Count, "A").End(xlUp).Row + 1
     For i = 1 To 3
       Cells(maxrow, i) = UserForm1.Controls("txtTextBox" & i).Value
      Next i
 Unload UserForm1
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        MsgBox "[登録]ボタンを使用してください"
        Cancel = True
    End If
End Sub


入力漏れ防止 作業手順 その5 所感


入門レベルでは決して足りない実務に必須のスキルとは ExcelVBAでは、テキストボックス毎に処理を記載しています。
この、素晴らしい回答をしてくれた方も、テキストボックス3つ位では、ありがたみが無いと仰っていました。
しかし、私は、テキストボックス3つでも、クラスモジュールを利用したいと思っています。
それは、汎用性があるからです。
勉強不足を痛感した瞬間でした。



ここがポイント

このコードは、クラスモジュールが、たとえ100個になっても、全然、平気なのです。
なぜ、クラスモジュールに関する書籍が無いのか不思議です。
少しの細工は、テキストボックスの冠に、txtをつけるようにして、Functionとクラスモジュールを利用することで、
メンテナンスも、コードの可読性も、向上します。
もっと、クラスモジュールを勉強したいと思いました。



まとめ
今回は、自分で正解には、たどりついていないので、コードは公開します。
是非とも、コードを眺めて、クラスモジュールを、何となくでもいいので、勉強してほしいと思います。
この処理を覚えると本当に便利です。
今回も最後まで読んでいただき、ありがとうございました。

サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す