【VBA】入力フォーム(UserForm)で手入力ミスを防ぐ方法(コピペOK)

VBA
スポンサーリンク

Contents

スポンサーリンク

この記事でできること

  • VBAのUserFormで入力フォームを作り、シートへの入力ミスを防げる
  • 必須チェック・数値チェック・日付チェックで不正な入力を弾ける(実務版)
  • コンボボックス(ドロップダウン選択)で入力内容を統一できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11


完成イメージ(Before / After)

Before(シートに直接入力):

  1. 入力者がセル位置を探して直接入力
  2. 全角/半角、日付書式がバラバラ
  3. 必須項目が空欄のまま提出される
  4. 管理者が毎回データを確認・修正(30分)

After(UserFormで入力):

  1. ボタンをクリックすると入力フォームが表示
  2. 各項目にラベル付きで分かりやすい
  3. 登録ボタンを押すと入力チェック → 問題なければ一覧表に自動追記
  4. 入力ミスが激減、確認作業が5分に

自分も以前、10人がシートに直接入力する運用をしていたが、セル位置の間違い・全角半角混在・必須欄の空白が頻発して毎回確認作業に30分かかっていた。入力ミスの後始末がしんどかった。UserFormで入力フォームを作ったら、入力ミスが激減。確認作業が5分で終わるようになった。入力ミスの後始末に疲れている人に、この記事でフォーム化を体験してほしい。

シート直接入力は「自由度が高い」のがメリットだが、裏を返せば「間違える自由」もある。フォームで入力を制限するのが最も確実なミス防止策。

なお、シートの入力規則(ドロップダウンリスト)で対応できるケースもある。入力規則(ドロップダウンリスト)をVBAで一括設定 を参照して使い分けを検討するとよい。


実行前の準備

この記事のコードは「コピペ+手順」が必要

UserFormは通常のマクロと異なり、VBEでフォームを手動作成してからコードを貼り付ける手順が必要。コードだけのコピペでは動かないため、手順どおりに進めてほしい。

シート構成を確認する

このコードは以下のシート構成を前提としている:

  • シート名「データ」— 入力データの一覧表
  • 1行目はヘッダー:A列「名前」、B列「カテゴリ」、C列「金額」、D列「日付」

Excelをマクロ有効ブック(.xlsm)で保存する

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(UserForm作成 → コード貼り付け → 実行)

STEP 1: VBEを開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

STEP 2: UserFormを挿入する

  1. VBEのメニュー →「挿入」→「ユーザーフォーム」
  2. 空のフォーム(UserForm1)が表示される

STEP 3: コントロールを配置する

ツールボックス(表示されない場合は「表示」→「ツールボックス」)から以下を配置する:

最小版のレイアウト:

コントロール プロパティ「(Name)」 プロパティ「Caption」 用途
Label lblName 名前 ラベル
TextBox txtName 名前の入力欄
Label lblCategory カテゴリ ラベル
TextBox txtCategory カテゴリの入力欄
Label lblAmount 金額 ラベル
TextBox txtAmount 金額の入力欄
CommandButton btnRegister 登録 登録ボタン
CommandButton btnClose 閉じる 閉じるボタン

コントロール名は必ず上の表のとおりに変更する。 プロパティウィンドウ(左下)で (Name) を書き換える。

STEP 4: コードを貼り付ける

  1. UserForm1をダブルクリック → コードウィンドウが開く
  2. 下のコードをそのまま貼り付ける

STEP 5: フォーム表示用のマクロを作る

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 以下のコードを貼り付ける:

Sub ShowInputForm()
    UserForm1.Show
End Sub
  1. ボタンに割り当てれば、シート上のボタンからフォームを開ける。方法は マクロをボタン1つで実行する方法 を参照。

コード(最小版)– テキストボックス3つ+登録ボタン

以下のコードをUserForm1のコードウィンドウに貼り付ける。


'============================================================
' ■ UserForm入力フォーム(最小版)
'   → テキストボックス3つ(名前・カテゴリ・金額)を一覧表に追記
'============================================================

'--- 登録ボタン
Private Sub btnRegister_Click()

    '--- ★書き換えポイント ---
    Dim sheetName As String
    sheetName = "データ"   '← 一覧表のシート名
    '--- ★ここまで ---

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(sheetName)

    '--- 最終行の次の行を取得
    Dim nextRow As Long
    nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    '--- フォームの値を一覧表に書き込み
    ws.Cells(nextRow, 1).Value = txtName.Value       '← A列: 名前
    ws.Cells(nextRow, 2).Value = txtCategory.Value   '← B列: カテゴリ
    ws.Cells(nextRow, 3).Value = txtAmount.Value      '← C列: 金額

    MsgBox "登録しました(" & nextRow - 1 & "件目)", vbInformation

    '--- 入力欄をクリア
    txtName.Value = ""
    txtCategory.Value = ""
    txtAmount.Value = ""
    txtName.SetFocus

End Sub

'--- 閉じるボタン
Private Sub btnClose_Click()
    Unload Me
End Sub

コードの流れ

  1. 登録ボタンがクリックされると btnRegister_Click が実行
  2. 一覧表の最終行+1を取得(セルの転記を自動化する方法 と同じ技術)
  3. フォームの値を各セルに書き込み
  4. 完了メッセージを表示
  5. 入力欄をクリアして次の入力に備える

コード(実務版)– 入力チェック+コンボボックス+日付

実務では「必須チェック」「数値チェック」「日付入力」「ドロップダウン選択」が欲しい。コンボボックスと入力チェックを追加した版。

実務版のレイアウト(追加コントロール):

コントロール プロパティ「(Name)」 プロパティ「Caption」 用途
Label lblDate 日付 ラベル
TextBox txtDate 日付の入力欄
ComboBox cmbCategory カテゴリの選択欄(コンボボックスに変更)

※ 最小版の txtCategory(TextBox)を cmbCategory(ComboBox)に置き換える。

コンボボックスで選択肢を絞れるようにしたら、入力の統一感が出て集計が楽になった。「原材料」「外注」「事務用品」などの表記ゆれがなくなり、ピボットテーブルが一発で決まるようになった。

以下のコードをUserForm1のコードウィンドウに貼り付ける(最小版と入れ替え)。


'============================================================
' ■ UserForm入力フォーム(実務版)
'   → 入力チェック+コンボボックス+日付+一覧表追記
'============================================================

'--- フォーム初期化(開いたときに1回だけ実行)
Private Sub UserForm_Initialize()

    '--- ★コンボボックスの選択肢を追加 ---
    With cmbCategory
        .AddItem "原材料"
        .AddItem "外注費"
        .AddItem "事務用品"
        .AddItem "交通費"
        .AddItem "その他"
    End With
    '--- ★ここまで ---

    '--- 日付欄に今日の日付を初期値として入れる
    txtDate.Value = Format(Date, "yyyy/MM/dd")

End Sub

'--- 登録ボタン
Private Sub btnRegister_Click()

    '--- ★書き換えポイント ---
    Dim sheetName As String
    sheetName = "データ"   '← 一覧表のシート名
    '--- ★ここまで ---

    '--- 入力チェック ---
    '--- 必須チェック: 名前
    If Trim(txtName.Value) = "" Then
        MsgBox "「名前」を入力してください。", vbExclamation
        txtName.SetFocus
        Exit Sub
    End If

    '--- 必須チェック: カテゴリ
    If cmbCategory.ListIndex = -1 Then
        MsgBox "「カテゴリ」を選択してください。", vbExclamation
        cmbCategory.SetFocus
        Exit Sub
    End If

    '--- 数値チェック: 金額
    If Not IsNumeric(txtAmount.Value) Or txtAmount.Value = "" Then
        MsgBox "「金額」には数値を入力してください。", vbExclamation
        txtAmount.SetFocus
        Exit Sub
    End If

    '--- 日付チェック: 日付
    If Not IsDate(txtDate.Value) Then
        MsgBox "「日付」を正しい形式で入力してください。" & vbCrLf & _
               "例: 2026/03/08", vbExclamation
        txtDate.SetFocus
        Exit Sub
    End If

    '--- 一覧表に書き込み ---
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(sheetName)

    Dim nextRow As Long
    nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    ws.Cells(nextRow, 1).Value = Trim(txtName.Value)           '← A列: 名前
    ws.Cells(nextRow, 2).Value = cmbCategory.Value             '← B列: カテゴリ
    ws.Cells(nextRow, 3).Value = CDbl(txtAmount.Value)         '← C列: 金額(数値変換)
    ws.Cells(nextRow, 4).Value = CDate(txtDate.Value)          '← D列: 日付(日付変換)

    MsgBox "登録しました(" & nextRow - 1 & "件目)", vbInformation

    '--- 入力欄をクリア(日付は残す)
    txtName.Value = ""
    cmbCategory.ListIndex = -1
    txtAmount.Value = ""
    txtName.SetFocus

End Sub

'--- 閉じるボタン
Private Sub btnClose_Click()
    Unload Me
End Sub

コードの流れ

  1. フォーム初期化: コンボボックスに選択肢を追加。日付欄に今日の日付を入れる
  2. 入力チェック: 必須チェック → 数値チェック → 日付チェック。不正な入力はMsgBoxで通知し、該当欄にフォーカス
  3. 一覧表追記: 最終行+1にフォームの値を書き込み。数値は CDbl、日付は CDate で型変換
  4. クリア処理: 名前・カテゴリ・金額をクリア。日付はそのまま残す(連続入力に便利)

フォーム表示マクロ ShowInputForm をボタン(マクロをボタン1つで実行する方法)に割り当てれば、シート上のボタンからフォームを開ける。


よくある落とし穴5選

1. コントロール名を変更せずにコードを貼り付けてエラー

原因: コードで txtName と書いているのに、実際のコントロール名が TextBox1 のままだとエラーになる。

対策: STEP 3 の表のとおりにコントロール名を変更する。プロパティウィンドウの (Name) を書き換える。

2. TextBoxの名前を変えずに10個並べて混乱

自分もこれでやらかした。TextBox1〜TextBox10のどれがどの項目か分からなくなり、コードの修正に1時間かかった。最初から txtName, txtAmount のように名前を付けるべきだった。

対策: コントロール名は「種類の略称+項目名」にする。例:TextBox → txt, ComboBox → cmb, Label → lbl, CommandButton → btn

3. コードを標準モジュールに貼り付けてしまった

原因: UserFormのコードは UserForm のコードウィンドウに貼り付ける。標準モジュールに貼ると動かない。

対策: UserForm1 をダブルクリックして開くコードウィンドウに貼り付ける。ShowInputForm だけは標準モジュールに書く。

4. フォームを閉じるときに×ボタンでエラー

原因: フォーム右上の×ボタン(UserForm_QueryClose)はデフォルトで Unload されるが、途中の処理状態によってはエラーになることがある。

対策: 閉じるボタン btnClose を用意し、Unload Me で安全に閉じる。×ボタンを無効にしたい場合は UserForm_QueryClose でキャンセルする。

5. 連続入力のたびにフォームが閉じてしまう

原因: 登録後に Unload Me を入れると、毎回フォームが閉じる。

対策: 実務版では登録後にフォームを閉じずに入力欄をクリアしている。連続入力が終わったら「閉じる」ボタンで閉じる。


FAQ

Q1: コンボボックスの選択肢をシートから読み込みたい

UserForm_Initialize でシートのデータを読み込む:


Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("マスタ")

Dim i As Long
For i = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    cmbCategory.AddItem ws.Cells(i, 1).Value
Next i

Q2: 入力後にセルを色分けしたい

登録処理の後に色分けを追加する。セルの値に応じて行を自動色分け の技術を組み合わせる。

Q3: 登録済みデータを編集したい

この記事は「新規追加」に絞っている。編集機能(既存行の読み込み→修正→上書き)はカスタマイズが必要。

Q4: UserFormをもっときれいにしたい

フォームのプロパティで Caption(タイトル)、BackColor(背景色)、Font(フォント)を変更できる。ただし、見た目よりも機能を優先するのが実務的。

Q5: ドロップダウン(入力規則)とUserFormはどちらがいい?

  • 入力規則(記事012): シートのセルにそのまま適用。少数項目・1人使い向け
  • UserForm(この記事): 複数項目の入力をまとめて管理。入力チェック付き。複数人使い向け

まとめ

  • VBAのUserFormで入力フォームを作り、シートへの入力ミスを防げる
  • IsNumeric / IsDate で入力チェックができる(実務版)
  • コンボボックスで選択式にすると入力内容が統一される
  • コントロール名は「種類の略称+項目名」にするのが鉄則

関連記事


次にやりたくなること


もっとカスタマイズしたい場合

「入力項目が10個以上ある」「マスタシートから動的にドロップダウンを生成したい」「編集・削除機能もほしい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。

相談時に伝えると話が早い情報:

  • Excel のバージョン / OS
  • 入力項目の一覧(何を入力するか)
  • 利用者の人数
  • 入力チェックの要件(必須・数値・日付・文字数制限など)

コメント

タイトルとURLをコピーしました