Contents
この記事でできること
- VBAのUserFormで本格的な入力画面を作り、一覧表にデータを追記できる
- TextBox・ComboBox・CommandButton・Labelの配置と命名ができる
- UserForm_Initializeでコンボボックスの初期値を設定できる
- CommandButton_Clickでシートへの転記処理が書ける
- 入力バリデーション(空欄チェック・数値チェック)ができる
- 実務版: 商品マスタ入力フォーム(名前・カテゴリ・価格・数量を入力→一覧表に追記)
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(シートに直接入力):
- 商品データをセルに直接入力
- 列を間違えて価格欄にテキストが入る
- カテゴリ名の表記がバラバラ(「食品」「食料品」「しょくひん」)
- 管理者が毎回データを確認・修正
After(UserFormで入力):
- ボタンをクリックすると入力フォームが表示
- 商品名・カテゴリ(ドロップダウン選択)・価格・数量を入力
- 「登録」ボタンを押すと入力チェック → 問題なければ一覧表に自動追記
- 入力ミスが激減、カテゴリも統一される
入力フォームで手入力ミスを防ぐ方法 で簡単なUserFormの作り方を紹介した。あの記事では名前・カテゴリ・金額の3項目だけだったが、実務では「もっと項目を増やしたい」「ドロップダウンで選択肢を絞りたい」「入力チェックをもっと厳しくしたい」という場面が出てくる。
自分も商品マスタの管理を任されたとき、InputBoxを何度も表示させて1項目ずつ入力させていたが、4項目で4回ダイアログが出るのは現実的ではなかった。UserFormで1画面にまとめたら、入力も確認も一発で済むようになった。入力作業のストレスが激減した。この記事で、同じように「もっと本格的な入力画面がほしい」と思っている人がフォーム化を実現できるようになればうれしい。
入力項目が1つだけならInputBoxのほうが手軽。InputBoxで条件を入力させて処理を動的に変える方法 を参照。
UserFormは「複数項目をまとめて入力させたい」ときの決定版。入力チェック+ドロップダウン選択で、入力ミスを仕組みで防げる。
実行前の準備
この記事のコードは「コピペ+手順」が必要
UserFormは通常のマクロと異なり、VBEでフォームを手動作成してからコードを貼り付ける手順が必要。コードだけのコピペでは動かないため、手順どおりに進めてほしい。
シート構成を確認する
このコードは以下のシート構成を前提としている:
- シート名「商品マスタ」— 商品データの一覧表
- 1行目はヘッダー:A列「商品名」、B列「カテゴリ」、C列「価格」、D列「数量」
シート名は正確に合わせる。 「商品マスタ」と「商品 マスタ」(半角スペースあり)は別名として扱われ、実行時エラーになる。
バックアップを取る
シートへの書き込み操作があるため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(UserForm作成 → コード貼り付け → 実行)
STEP 1: VBEを開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
STEP 2: UserFormを挿入する
- VBEのメニュー →「挿入」→「ユーザーフォーム」
- 空のフォーム(UserForm1)とツールボックスが表示される
- ツールボックスが表示されない場合は「表示」→「ツールボックス」
STEP 3: コントロールを配置する
ツールボックスからコントロールを選んで、フォーム上にドラッグして配置する。
最小版のレイアウト:
| コントロール | プロパティ「(Name)」 | プロパティ「Caption」 | 用途 |
|---|---|---|---|
| Label | lblName | 商品名 | ラベル |
| TextBox | txtName | — | 商品名の入力欄 |
| Label | lblPrice | 価格 | ラベル |
| TextBox | txtPrice | — | 価格の入力欄 |
| CommandButton | btnRegister | 登録 | 登録ボタン |
| CommandButton | btnClose | 閉じる | 閉じるボタン |
コントロール名は必ず上の表のとおりに変更する。 プロパティウィンドウ(左下)で (Name) を書き換える。
STEP 4: コードを貼り付ける
- UserForm1をダブルクリック → コードウィンドウが開く
- 下のコードをそのまま貼り付ける
STEP 5: フォーム表示用のマクロを作る
- VBEのメニュー →「挿入」→「標準モジュール」
- 以下のコードを貼り付ける:
Sub 商品マスタ入力フォームを開く()
UserForm1.Show
End Sub
- ボタンに割り当てれば、シート上のボタンからフォームを開ける。方法は マクロをボタン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列: 価格 |
コードの流れ
- 登録ボタンがクリックされると
btnRegister_Clickが実行 Cells.End(xlUp).Row + 1で一覧表の最終行+1を取得(データの最終行・最終列を正確に取得する方法 と同じ技術)- フォームの値を各セルに書き込み
- 完了メッセージを表示
- 入力欄をクリアして次の入力に備える
コード(実務版)– 商品マスタ入力フォーム(名前・カテゴリ・価格・数量→一覧表に追記)
実務では「カテゴリはドロップダウンで選ばせたい」「数量と価格は数値チェックしたい」「空欄のまま登録させたくない」が必要になる。バリデーション+コンボボックス付きの実務版。
実務版のレイアウト(最小版から追加・変更するコントロール):
| コントロール | プロパティ「(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:数量 |
コードの流れ
- フォーム初期化(UserForm_Initialize): コンボボックスに選択肢を追加。フォームのタイトルを設定
- 入力バリデーション: 商品名の空欄チェック → カテゴリの選択チェック → 価格の数値チェック → 数量の整数チェック。不正な入力はMsgBoxで通知し、該当欄にフォーカス
- 一覧表追記: 最終行+1にフォームの値を書き込み。価格は
CDbl、数量はCLngで型変換 - 完了メッセージ: 登録内容を確認表示
- クリア処理: 全入力欄をクリアして次の入力に備える
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を返す。整数チェックには CLng と CDbl の比較が必要 |
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
関連記事
- 入力フォームで手入力ミスを防ぐ方法 — UserFormの基本を復習したい場合はこちら
- InputBoxで条件を入力させて処理を動的に変える方法 — 入力項目が1つだけならInputBoxが手軽
次にやりたくなること
- 入力規則(ドロップダウンリスト)をVBAで一括設定: シート上のセルにもドロップダウンを設定して、フォームを使わない人の入力ミスも防ぎたい場合
- InputBoxで条件を入力させて処理を動的に変える方法: フォームを作るほどではない簡易入力。1項目だけの条件入力ならInputBoxが手軽
もっとカスタマイズしたい場合
「入力項目が10個以上ある」「マスタシートからコンボボックスの選択肢を動的に生成したい」「編集・削除機能もほしい」「ListBoxで登録済みデータを一覧表示したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- 入力項目の一覧(何を入力するか)
- 利用者の人数
- 入力チェックの要件(必須・数値・日付・文字数制限など)
- 編集・削除機能の要否


コメント