ユーザー入力の検証
メニューを表示するにはスワイプしてください
前章の保存ボタンは、cmdSave_Clickでデータを事前にチェックしないため、空白のCompany Nameや不正なメールアドレスでもCustomersテーブルに書き込んでしまいます。バリデーションは保存前に実行されるステップであり、問題が簡単に修正できるうちに発見し、ワークシートに不正なデータが残るのを防ぎます。
必須項目
最も基本的なチェック:このTextBoxがまだ空かどうか?
If Trim(txtCompanyName.Value) = "" Then
MsgBox "Company Name is required."
txtCompanyName.SetFocus
Exit Sub
End If
ここでTrimが重要なのは、ユーザーがスペースだけを入力した場合、単純な= ""チェックでは空文字列と見なされず、実際には使えない値であるにもかかわらず通過してしまうためです。SetFocusはカーソルを問題のコントロールに直接移動させるため、ユーザーがどの項目を修正すべきか探す手間が省け、フォームの使い勝手が大きく向上します。
数値バリデーション
IsNumericは、値が数値に変換可能かどうかをチェックします。実際に変換してエラーになるリスクを避けられます。
If Not IsNumeric(txtReorderLevel.Value) Then
MsgBox "Reorder Level must be a number."
txtReorderLevel.SetFocus
Exit Sub
End If
このチェックは、上記のスクリーンショットのように数値フィールドに"twenty"と入力された場合に検出できます。このチェックを通過した後で初めて、CInt(txtReorderLevel.Value)のようなコードを安全に記述できます。先にバリデーション、次に変換を行うことで、予期しない変換エラーを防げます。
日付バリデーション
IsDateは、数値の代わりに日付に対して同じ考え方を適用します。
If Not IsDate(txtOrderDate.Value) Then
MsgBox "Order Date must be a valid date."
txtOrderDate.SetFocus
Exit Sub
End If
すべての問題を一度にまとめて表示するエラーメッセージ
上記の3つのチェックは、問題を1つ見つけた時点でExit Subします。短いフォームなら問題ありませんが、長いフォームでは1つ修正するたびに次のエラーが出てきて、ユーザーにとっては煩わしいものです。より洗練されたパターンでは、すべての問題をリストアップしてから、1つのまとめたメッセージを表示します。
Private Sub cmdSave_Click()
Dim errors As String
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
End If
If Not IsNumeric(txtReorderLevel.Value) Then
errors = errors & "- Reorder Level must be a number" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, _
vbExclamation
Exit Sub
End If
' ... all checks passed, safe to save now
End Sub
これは前章の在庫アラートマクロと同じ文字列構築テクニックです。errorsは空で始まり、各チェックで失敗した場合に1行ずつ追加されます。すべてのチェックが終わった後でerrorsが空かどうかを確認するため、ユーザーは一度にすべての入力ミスを確認でき、何度も修正と再入力を繰り返す必要がありません。
タスク
- 前章の課題で作成した
cmdSave_Clickを書き換え、会社名、連絡先、メールアドレスがすべて空白でないかを確認し、エラー文字列を作成。 - 練習用に4つ目のTextBox(txtReorderLevel)を追加し、IsNumericで検証。
- すべての問題を一覧表示するMsgBoxを1つだけ表示し(アイコンはvbExclamation)、エラーが空の場合のみListRows.Addのコードを実行。
- すべてのフィールドを空白のまま保存をクリックしてテストし、すべてのエラー行が1つのメッセージに表示されることを確認。
1. エラー文字列の作成
Stringの先頭でerrors型変数(cmdSave_Click)を宣言し、空で初期化。- 3つの各フィールドについて、セクション5.3と同じく
Trim(...) = ""で空白をチェックし、空の場合は即座にerrorsを表示したり Sub を終了するのではなく、1行ずつMsgBoxに追加。 - 各行の末尾に
vbNewLineを付けることで、最終メッセージで各問題が1行ずつ表示される。
2. txtReorderLevelの追加
- このTextBoxは数値検証の練習用であり、
tblCustomersの実際の列には対応しないため、後でnewRowに書き込む必要はない。 - デザインビュー(Shift+F7)で他の3つのTextBoxと同様にLabel付きでフォームに追加。
IsNumericで.Valueの生テキストをチェックし、失敗した場合は空白チェックと同様にerrorsに1行追加。
3. 1つのMsgBoxでまとめて表示し、続行
- セクション5.3の例と同様に、
If errors <> "" Thenで1つのMsgBox(vbExclamation付き)を表示し、Exit Sub。 ListRows.Addのコードは、そのIfブロックの後(Elseの中ではなく)に配置し、バリデーションがすべて通った場合のみ実行。
4. すべて空白でテスト
- 何も入力せずに保存をクリック。
- 4つの問題(会社名、連絡先、メールアドレス、発注点)がすべて1つの
MsgBoxに一覧表示されることを確認(最初のエラーで止まらず、すべてまとめて表示されるのがこの演習のポイント)。
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Dim errors As String
' --- Validation ---
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
End If
If Trim(txtContact.Value) = "" Then
errors = errors & "- Contact is required" & vbNewLine
End If
If Trim(txtEmail.Value) = "" Then
errors = errors & "- Email is required" & vbNewLine
End If
If Not IsNumeric(txtReorderLevel.Value) Then
errors = errors & "- Reorder Level must be a number" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
Exit Sub
End If
' --- All checks passed — safe to save now ---
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = cboStatus.Value
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
フォームを実行し、すべてのフィールドを空白のまま保存をクリックすると、警告アイコン付きのMsgBoxが1つ表示され、4つの未入力・無効フィールドがすべて一覧表示される。すべて正しく入力するまで tblCustomers には行が追加されない。
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください