【VBA】ユーザーフォーム(UserForm)で本格的な入力画面を作る方法(コピペOK)

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

この記事でできること

  • VBAのUserFormで本格的な入力画面を作り、一覧表にデータを追記できる
  • TextBox・ComboBox・CommandButton・Labelの配置と命名ができる
  • UserForm_Initializeでコンボボックスの初期値を設定できる
  • CommandButton_Clickでシートへの転記処理が書ける
  • 入力バリデーション(空欄チェック・数値チェック)ができる
  • 実務版: 商品マスタ入力フォーム(名前・カテゴリ・価格・数量を入力→一覧表に追記)

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


完成イメージ(Before / After)

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

  1. 商品データをセルに直接入力
  2. 列を間違えて価格欄にテキストが入る
  3. カテゴリ名の表記がバラバラ(「食品」「食料品」「しょくひん」)
  4. 管理者が毎回データを確認・修正

After(UserFormで入力):

  1. ボタンをクリックすると入力フォームが表示
  2. 商品名・カテゴリ(ドロップダウン選択)・価格・数量を入力
  3. 「登録」ボタンを押すと入力チェック → 問題なければ一覧表に自動追記
  4. 入力ミスが激減、カテゴリも統一される

入力フォームで手入力ミスを防ぐ方法 で簡単なUserFormの作り方を紹介した。あの記事では名前・カテゴリ・金額の3項目だけだったが、実務では「もっと項目を増やしたい」「ドロップダウンで選択肢を絞りたい」「入力チェックをもっと厳しくしたい」という場面が出てくる。

自分も商品マスタの管理を任されたとき、InputBoxを何度も表示させて1項目ずつ入力させていたが、4項目で4回ダイアログが出るのは現実的ではなかった。UserFormで1画面にまとめたら、入力も確認も一発で済むようになった。入力作業のストレスが激減した。この記事で、同じように「もっと本格的な入力画面がほしい」と思っている人がフォーム化を実現できるようになればうれしい。

入力項目が1つだけならInputBoxのほうが手軽。InputBoxで条件を入力させて処理を動的に変える方法 を参照。

UserFormは「複数項目をまとめて入力させたい」ときの決定版。入力チェック+ドロップダウン選択で、入力ミスを仕組みで防げる。


実行前の準備

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

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

シート構成を確認する

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

  • シート名「商品マスタ」— 商品データの一覧表
  • 1行目はヘッダー:A列「商品名」、B列「カテゴリ」、C列「価格」、D列「数量」

シート名は正確に合わせる。 「商品マスタ」と「商品 マスタ」(半角スペースあり)は別名として扱われ、実行時エラーになる。

バックアップを取る

シートへの書き込み操作があるため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。

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

拡張子が .xlsx のままだとマクロが保存できない。

  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)とツールボックスが表示される
  3. ツールボックスが表示されない場合は「表示」→「ツールボックス」

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

ツールボックスからコントロールを選んで、フォーム上にドラッグして配置する。

最小版のレイアウト:

コントロール プロパティ「(Name)」 プロパティ「Caption」 用途
Label lblName 商品名 ラベル
TextBox txtName 商品名の入力欄
Label lblPrice 価格 ラベル
TextBox txtPrice 価格の入力欄
CommandButton btnRegister 登録 登録ボタン
CommandButton btnClose 閉じる 閉じるボタン

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

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

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

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

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

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

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

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

まずはUserFormの基本。商品名と価格の2項目だけをシートに追記する最小コード。バリデーション(入力チェック)は入っていないため、まずは動かして感覚をつかむのが目的。入力チェックは実務版で追加する。


'============================================================
' ■ UserForm入力フォーム(最小版)
'   → テキストボックス2つ(商品名・価格)を一覧表に追記
'============================================================

'--- 登録ボタン
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 = txtPrice.Value    '← B列: 価格

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

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

End Sub

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

書き換えポイント

変数・箇所 説明 初期値
"商品マスタ" 一覧表のシート名 「商品マスタ」
ws.Cells(nextRow, 1) 書き込み先の列番号。1=A列、2=B列 A列: 商品名、B列: 価格

コードの流れ

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

コード(実務版)– 商品マスタ入力フォーム(名前・カテゴリ・価格・数量→一覧表に追記)

実務では「カテゴリはドロップダウンで選ばせたい」「数量と価格は数値チェックしたい」「空欄のまま登録させたくない」が必要になる。バリデーション+コンボボックス付きの実務版。

実務版のレイアウト(最小版から追加・変更するコントロール):

コントロール プロパティ「(Name)」 プロパティ「Caption」 用途
Label lblCategory カテゴリ ラベル
ComboBox cmbCategory カテゴリの選択欄(ドロップダウン)
Label lblQuantity 数量 ラベル
TextBox txtQuantity 数量の入力欄

※ 最小版の2つ(lblName, txtName, lblPrice, txtPrice, btnRegister, btnClose)はそのまま使う。上の4つを追加する。

コンボボックスでカテゴリを選択式にしたら、「食品」「食料品」「しょくひん」のような表記ゆれがなくなった。集計やピボットテーブルが一発で決まるようになって快適。コンボボックスの考え方は 入力規則(ドロップダウンリスト)をVBAで一括設定 と同じ。

エラー処理の詳細は エラー処理(On Error)で止まらないマクロを作る方法 を参照。

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


'============================================================
' ■ UserForm入力フォーム(実務版)
'   → 商品マスタ入力フォーム
'   → 商品名・カテゴリ(ComboBox)・価格・数量を入力→一覧表に追記
'   → 入力バリデーション(空欄チェック・数値チェック)付き
'============================================================

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

    '--- ★コンボボックスの選択肢を追加 ---
    With cmbCategory
        .AddItem "食品"
        .AddItem "飲料"
        .AddItem "日用品"
        .AddItem "文房具"
        .AddItem "その他"
    End With
    '--- ★ここまで ---

    '--- フォームのタイトルを設定
    Me.Caption = "商品マスタ入力"

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(txtPrice.Value) Or txtPrice.Value = "" Then
        MsgBox "「価格」には数値を入力してください。", vbExclamation
        txtPrice.SetFocus
        Exit Sub
    End If

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

    If CLng(txtQuantity.Value) <> CDbl(txtQuantity.Value) Then
        MsgBox "「数量」には整数を入力してください。", vbExclamation
        txtQuantity.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(txtPrice.Value)       '← C列: 価格(数値変換)
    ws.Cells(nextRow, 4).Value = CLng(txtQuantity.Value)    '← D列: 数量(整数変換)

    MsgBox "登録しました(" & nextRow - 1 & "件目)" & vbCrLf & _
           "商品名: " & Trim(txtName.Value) & vbCrLf & _
           "カテゴリ: " & cmbCategory.Value & vbCrLf & _
           "価格: " & Format(CDbl(txtPrice.Value), "#,##0") & " 円" & vbCrLf & _
           "数量: " & txtQuantity.Value, vbInformation

    '--- 入力欄をクリア(連続入力に備える)
    txtName.Value = ""
    cmbCategory.ListIndex = -1
    txtPrice.Value = ""
    txtQuantity.Value = ""
    txtName.SetFocus

End Sub

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

書き換えポイント

変数・箇所 説明 初期値
"商品マスタ" 一覧表のシート名 「商品マスタ」
.AddItem "食品" コンボボックスの選択肢。業務に合わせて変更 食品/飲料/日用品/文房具/その他
ws.Cells(nextRow, 1)4 書き込み先の列番号。シートの列構成に合わせる A:商品名、B:カテゴリ、C:価格、D:数量

コードの流れ

  1. フォーム初期化(UserForm_Initialize): コンボボックスに選択肢を追加。フォームのタイトルを設定
  2. 入力バリデーション: 商品名の空欄チェック → カテゴリの選択チェック → 価格の数値チェック → 数量の整数チェック。不正な入力はMsgBoxで通知し、該当欄にフォーカス
  3. 一覧表追記: 最終行+1にフォームの値を書き込み。価格は CDbl、数量は CLng で型変換
  4. 完了メッセージ: 登録内容を確認表示
  5. クリア処理: 全入力欄をクリアして次の入力に備える

cmbCategory.ListIndex = -1 はコンボボックスの選択を解除する。-1 は「何も選択されていない」状態。

Trim(txtName.Value) で前後の空白を除去してから保存している。ユーザーが「 りんご 」のように前後に空白を入れても、「りんご」として保存される。


Me.Hide と Unload Me の使い分け

UserFormを閉じる方法は2つある。迷ったら Unload Me を使えばOK。

操作 動作 フォームの値 使う場面
Unload Me フォームを完全に閉じる(メモリから破棄) 消える フォームを閉じて終了する場合(この記事の用途)
Me.Hide フォームを非表示にする(メモリに残る) 残る 呼び出し元のコードでフォームの値を参照したい場合

この記事の実務版では Unload Me を使っている。登録処理はフォーム内で完結しており、呼び出し元で値を参照する必要がないため。この記事の用途では Unload Me で十分。

Me.Hide が必要な例:


' --- 標準モジュール側 ---
Sub 入力値を取得する()
    UserForm1.Show       '← フォーム表示
    ' ↓ Me.Hide で閉じた場合、ここでフォームの値を参照できる
    Dim name As String
    name = UserForm1.txtName.Value
    MsgBox "入力された商品名: " & name
    Unload UserForm1     '← 参照が終わったら破棄
End Sub

よくある落とし穴5選

# 落とし穴 原因 対策
1 コントロール名を変更せずにコードを貼り付けてエラー コードで txtName と書いているのに、実際のコントロール名が TextBox1 のまま プロパティウィンドウの (Name) を表のとおりに書き換える
2 コードを標準モジュールに貼り付けて動かない UserFormのコードはUserFormのコードウィンドウに書く。標準モジュールに書くと txtName が見つからずエラー UserForm1をダブルクリックして開くコードウィンドウに貼り付ける。商品マスタ入力フォームを開く だけが標準モジュール
3 Unload Meした後にフォームの値を参照してエラー Unload Me するとフォームの値は消える。閉じた後に UserForm1.txtName.Value を参照するとエラー 呼び出し元で値を使いたい場合は Me.Hide を使い、参照後に Unload UserForm1 する
4 コンボボックスの選択肢が表示されない UserForm_Initialize にAddItemを書いていない。または UserForm_Initialize の綴りが間違っている UserForm_Initialize イベントに .AddItem を書く。VBEの左上プルダウンから UserForm を選び、右上から Initialize を選ぶと自動生成される
5 数量に小数を入力してもエラーにならない IsNumeric は小数もTrueを返す。整数チェックには CLngCDbl の比較が必要 CLng(txtQuantity.Value) <> CDbl(txtQuantity.Value) で整数かどうかを判定する

自分もTextBox1〜TextBox10のまま10個並べて、どのTextBoxがどの項目か分からなくなったことがある。コード修正に1時間かかった。それ以来、txtName, txtPrice のように必ず名前を付けるようにしている。コントロール名の命名規則は「種類の略称+項目名」(txt, cmb, lbl, btn)が鉄則。

業務に応じて価格の範囲チェック(0以上など)を追加するのもおすすめ。If CDbl(txtPrice.Value) < 0 Then のような条件を入力バリデーションに追加すれば、マイナスの価格を弾ける。


FAQ

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

UserForm_Initialize でシートのデータをループして AddItem する:


Private Sub 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
End Sub

Q2: 登録後にフォームを閉じずに続けて入力したい

実務版はこの設計になっている。登録後に Unload Me ではなく入力欄の .Value = "".ListIndex = -1 でクリアしているため、フォームが開いたまま連続入力できる。入力が終わったら「閉じる」ボタンで閉じる。

Q3: フォームの×ボタン(右上の閉じるボタン)を無効にしたい

UserForm_QueryClose イベントで制御する:


Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        Cancel = True
        MsgBox "「閉じる」ボタンから閉じてください。", vbExclamation
    End If
End Sub

Q4: UserFormとInputBoxはどちらを使うべき?

  • InputBox(記事077: 入力項目が1つだけ。手軽に使いたい場合
  • UserForm(この記事): 入力項目が複数。入力チェック・ドロップダウン選択が必要な場合

入力項目が1つなら InputBoxで条件を入力させて処理を動的に変える方法 のほうが手軽。

Q5: 登録済みデータを編集・削除したい

この記事は「新規追加」に絞っている。編集機能(既存行の読み込み→修正→上書き)や削除機能はカスタマイズが必要。編集・削除機能付きの本格的な業務フォームが必要な場合はココナラで相談できる。


まとめ

  • VBAのUserFormで本格的な入力画面を作り、一覧表にデータを追記できる
  • コントロール名は「種類の略称+項目名」(txt, cmb, lbl, btn)にするのが鉄則
  • UserForm_Initialize でコンボボックスの初期値を設定
  • 入力バリデーション(空欄チェック・数値チェック・整数チェック)で入力ミスを防ぐ
  • Unload Me はフォームを完全に閉じる。値を残したい場合は Me.Hide

関連記事


次にやりたくなること


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

「入力項目が10個以上ある」「マスタシートからコンボボックスの選択肢を動的に生成したい」「編集・削除機能もほしい」「ListBoxで登録済みデータを一覧表示したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。

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

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

コメント

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