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

VBA
スポンサーリンク
スポンサーリンク

完成イメージ(Before / After)

Before(シートに直接入力)

Before(実行前)のExcel画面
A(モデル名) B(ライン) C(数値)
1 モデル名 ライン 数値
2 Model-A ライン1 15.2
3 model-a ライン1 14.8
4 Model A ライン1
5 Model-A Line1 15.0

表記揺れ・空欄・全角半角混在が頻発。集計が壊れる。

After(UserFormで入力)

After(実行後)のExcel画面
A(モデル名) B(ライン) C(数値)
1 モデル名 ライン 数値
2 Model-A ライン1 15.2
3 Model-A ライン1 14.8
4 Model-A ライン1 15.0
5 Model-B ライン2 16.1

コンボボックスで選択するため表記が統一。入力チェックで空欄も防止。

なお、シートの入力規則(ドロップダウンリスト)で対応できるケースもある。入力規則(ドロップダウンリスト)を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)に置き換える。

コンボボックスで選択肢を絞れるようにしたら、入力の統一感が出て集計が楽になった。「原材料」「外注」「事務用品」などの表記ゆれがなくなり、ピボットテーブルが一発で決まるようになった。入力チェックとコンボボックスの組み合わせは、フォーム設計の定番パターン。シートの入力規則(入力規則をVBAで一括設定)と合わせて使うとさらに堅牢になる。

以下のコードを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 のコードウィンドウに貼り付ける。標準モジュールに貼ると動かない。

自分も最初このミスをやった。エラーメッセージを読んでも意味が分からず、30分悩んだ。VBEの左側のツリーで「UserForm1」をダブルクリックして開くウィンドウに貼り付ける、という手順が重要。

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

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

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

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

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

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

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

VBAのUserFormが表示されないときの対処法

「マクロを実行してもフォームが出てこない」という場合、原因はUserFormのオブジェクトがVBEで作成されていないことだ。UserFormは標準モジュールにコードを書くだけでは動かない。VBEで「挿入」→「ユーザーフォーム」を選んでフォームを作成し、コントロールを配置してからコードを貼り付ける必要がある。

VBAのUserFormで入力チェックが効かないときの対処法

「必須チェックを入れたのに空欄で登録できてしまう」という場合、原因は登録ボタンのイベントにチェック処理が正しく紐づいていないことだ。登録ボタンをダブルクリックして表示されるイベントプロシージャ内にチェック処理を書いていることを確認し、Exit Sub で処理を中断する分岐が正しく動作しているかテストすれば解決する。

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はどちらがいい?

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

まとめ

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

関連記事

次にやりたくなること

コメント

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