- 技術 💻
VBAユーザーフォームの作り方|入力・登録・閉じるまでコード付き
VBAのユーザーフォーム(UserForm)は、テキストボックスやコンボボックスを並べて、複数の項目を一度に入力してもらうための自作の画面です。 作り方の流れは「フォームを挿入する→コントロールを置く→表示するコードと、ボタンを押したときのコードを書く」の3段階です。
この記事では、入力チェックからシートへの登録、入力欄のクリア、閉じる処理までを、標準モジュール側とフォーム側に分けた通しのコードで載せます。Unload と Hide、モーダルとモードレスの選び方、イベントの発生順も表にまとめます。
確認環境:Microsoft Learn の VBA リファレンス(UserForm オブジェクト、Show・Hide メソッド、Load・Unload ステートメント、Initialize・Activate・QueryClose・Terminate イベント、ShowModal プロパティ、TextBox・ComboBox・ListBox・CheckBox・OptionButton・CommandButton・Label コントロール、AddItem・SetFocus メソッド、ListIndex・Style・Cancel プロパティ、IsDate・IsNumeric 関数)と「Create a user form」を 2026-10-06 に開いて確認し、フォーム側のコードはその定義に沿って書いています。標準モジュール側の関数(入力チェックとシートへの登録)は、LibreOffice 24.2.7.2(Linux、ロケールは日本語)の Basic を VBA 互換モード(Option VBASupport 1)にして動かし、結果を載せています。
この記事の結論
- 処理の流れは4つです。Initialize で選択肢を入れる → 登録ボタンで未入力・数値・日付を確かめる → 最終行の次の行に書く → 入力欄を空にする。
- 入力チェックとシートへの書き込みは標準モジュールに置き、フォーム側は「コントロールの値を渡す」「結果を表示する」だけにします。フォームを開かずに関数だけを試せます。
- 閉じるときは Unload、値を残して隠すときは Hide を使います。
- 入力中にシートも操作してもらうなら
Show vbModeless、入力が終わるまで待つなら既定のモーダルで表示します。 - ×ボタンは QueryClose イベントで扱えます。 CloseMode が vbFormControlMenu(0)のときが×ボタンです。
ユーザーフォームの早見表
| やりたいこと | 書き方 | 書く場所 |
|---|---|---|
| フォームを表示する | frmEntry.Show |
標準モジュール |
| シートを操作できる状態で表示する | frmEntry.Show vbModeless |
標準モジュール |
| 選択肢を入れる | cboPerson.AddItem "佐藤" |
フォームの UserForm_Initialize |
| 入力値を読む | txtItem.Value |
フォームの各イベント |
| 何も選ばれていないかを調べる | cboPerson.ListIndex = -1 |
フォームの各イベント |
| ボタンが押されたときの処理 | Private Sub cmdRegister_Click() |
フォーム |
| 入力欄にカーソルを移す | txtItem.SetFocus |
フォーム |
| フォームを閉じる(破棄する) | Unload Me |
フォーム |
| 値を残したまま隠す | Me.Hide |
フォーム |
| ×ボタンで閉じるのを止める | QueryClose で Cancel = True |
フォームの UserForm_QueryClose |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VBAユーザーフォームの作り方|入力・登録・閉じるまでコード付き」
MsgBox・InputBoxとの使い分け
| 場面 | 選ぶもの |
|---|---|
| メッセージを出して、はい・いいえを選んでもらう | MsgBox |
| 値を1つだけ入力してもらう | InputBox |
| 複数の項目を一度に入力してもらう | ユーザーフォーム |
| 選択肢から選んでもらう、チェックを付けてもらう | ユーザーフォーム |
| 入力の内容を確かめて、その場でやり直してもらう | ユーザーフォーム |
項目が2つ以上になったら、ユーザーフォームが向いています。入力欄を一画面に並べられ、どの項目に問題があるかをその画面の中で伝えられます。
作るもの:備品の注文を登録するフォーム
シート「注文一覧」に、1件ずつ行を足していくフォームを作ります。
| 列 | 見出し | 入力に使うコントロール |
|---|---|---|
| A | 日付 | テキストボックス |
| B | 担当 | コンボボックス |
| C | 品名 | テキストボックス |
| D | 数量 | テキストボックス |
| E | 急ぎ | チェックボックス |
手順1:フォームを挿入してコントロールを置く
- Visual Basic Editor を開きます。
- [挿入]メニューの[ユーザーフォーム]を選びます。
- プロパティ ウィンドウで、フォームの名前や Caption(タイトル バーの文字)を変えます。
ここまでは Microsoft Learn の「Create a user form」に載っている手順です。続けて、ツールボックスからコントロールをフォームに置き、プロパティ ウィンドウで名前を付けます。
| コントロール | (オブジェクト名) | そのほかに設定するプロパティ | 役割 |
|---|---|---|---|
| UserForm | frmEntry | Caption:注文の登録 | フォーム本体 |
| TextBox | txtDate | 日付 | |
| ComboBox | cboPerson | Style:2 - fmStyleDropDownList | 担当(一覧から選ぶ) |
| TextBox | txtItem | 品名 | |
| TextBox | txtQty | 数量 | |
| CheckBox | chkUrgent | Caption:急ぎ | 急ぎかどうか |
| CommandButton | cmdRegister | Caption:登録 | シートに書き込む |
| CommandButton | cmdClose | Caption:閉じる、Cancel:True | フォームを閉じる |
| Label | lblMessage | Caption:(空) | 入力チェックの結果を表示する |
- 名前は「種類の略+役割」 にしておくと、コードを読むときにコントロールの種類が分かります(txt、cbo、chk、cmd、lbl)。
- ComboBox の Style を fmStyleDropDownList(2) にすると、一覧から選ぶだけの入力になります。既定の fmStyleDropDownCombo(0)は、一覧から選ぶことも、文字を打ち込むこともできます。
- CommandButton の Cancel を True にすると、リファレンスの説明のとおり、フォームがアクティブなときに Esc キーでそのボタンを選べます。Cancel を True にできるボタンは、1つのフォームに1つだけです。
- 各入力欄の左に、「日付」「担当」などの文字を表示する Label も置きます。
手順2:標準モジュールのコード(入力チェックと登録)
標準モジュールを1つ追加して、次のコードを貼ります。
Option Explicit
Public Const SHEET_NAME As String = "注文一覧"
' フォームを表示する(ボタンやマクロ一覧から呼ぶ入口)
Public Sub ShowEntryForm()
frmEntry.Show
End Sub
' 入力値を確かめる。問題がなければ空文字、あればメッセージを返す
Public Function ValidateEntry(ByVal orderDate As String, ByVal person As String, _
ByVal itemName As String, ByVal qty As String) As String
If Trim(orderDate) = "" Then
ValidateEntry = "日付を入力してください。"
ElseIf Not IsDate(orderDate) Then
ValidateEntry = "日付は 2026/10/06 の形で入力してください。"
ElseIf Trim(person) = "" Then
ValidateEntry = "担当を選んでください。"
ElseIf Trim(itemName) = "" Then
ValidateEntry = "品名を入力してください。"
ElseIf Trim(qty) = "" Then
ValidateEntry = "数量を入力してください。"
ElseIf Not IsNumeric(qty) Then
ValidateEntry = "数量は数字で入力してください。"
ElseIf CDbl(qty) <> Int(CDbl(qty)) Or CDbl(qty) < 1 Then
ValidateEntry = "数量は 1 以上の整数で入力してください。"
Else
ValidateEntry = ""
End If
End Function
' 最終行の次の行に1件書き込み、書いた行番号を返す
Public Function AppendEntry(ByVal ws As Worksheet, ByVal orderDate As String, _
ByVal person As String, ByVal itemName As String, _
ByVal qty As String, ByVal isUrgent As Boolean) As Long
Dim r As Long
If IsEmpty(ws.Range("A1").Value) Then
ws.Range("A1:E1").Value = Array("日付", "担当", "品名", "数量", "急ぎ")
End If
r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
ws.Cells(r, 1).Value = CDate(orderDate)
ws.Cells(r, 2).Value = person
ws.Cells(r, 3).Value = Trim(itemName)
ws.Cells(r, 4).Value = CLng(qty)
If isUrgent Then
ws.Cells(r, 5).Value = "急ぎ"
Else
ws.Cells(r, 5).Value = ""
End If
AppendEntry = r
End Function
| プロシージャ | 役割 |
|---|---|
| ShowEntryForm | フォームを表示する入口。シート上のボタンに登録したり、マクロの一覧から動かしたりする |
| ValidateEntry | 入力値を上から順に確かめ、最初に見つかった問題のメッセージを返す。問題がなければ空文字 |
| AppendEntry | A列の最終行の次の行に1件書き、書いた行番号を返す。A1 が空なら見出しも書く |
入力チェックで使っている関数は、リファレンスで次のように説明されています。
| 関数 | 説明 |
|---|---|
| IsDate | 式が日付であるか、有効な日付や時刻として認識できるときに True を返す |
| IsNumeric | 式全体が数値として認識できるときに True を返す。"45 Help" は False |
ValidateEntryの結果
フォームを開かずに、関数だけを呼び出して確かめた結果です。
| 日付 | 担当 | 品名 | 数量 | 返ってきたメッセージ |
|---|---|---|---|---|
| (空) | 佐藤 | ノート | 3 | 日付を入力してください。 |
| 10月6日ごろ | 佐藤 | ノート | 3 | 日付は 2026/10/06 の形で入力してください。 |
| 2026/13/40 | 佐藤 | ノート | 3 | 日付は 2026/10/06 の形で入力してください。 |
| 2026/10/06 | (空) | ノート | 3 | 担当を選んでください。 |
| 2026/10/06 | 佐藤 | (空白だけ) | 3 | 品名を入力してください。 |
| 2026/10/06 | 佐藤 | ノート | (空) | 数量を入力してください。 |
| 2026/10/06 | 佐藤 | ノート | 3冊 | 数量は数字で入力してください。 |
| 2026/10/06 | 佐藤 | ノート | 1.5 | 数量は 1 以上の整数で入力してください。 |
| 2026/10/06 | 佐藤 | ノート | 0 | 数量は 1 以上の整数で入力してください。 |
| 2026/10/06 | 佐藤 | ノート | -2 | 数量は 1 以上の整数で入力してください。 |
| 2026/10/06 | 佐藤 | ノート | 3 | (空文字=問題なし) |
AppendEntryの結果
何も入っていないシートに対して、2回続けて呼び出しました。
r = AppendEntry(ws, "2026/10/06", "佐藤", " ノート B5 ", "3", False) ' r は 2
r = AppendEntry(ws, "2026/10/07", "鈴木", "付箋", "10", True) ' r は 3
呼び出し後のシートです。
| 日付 | 担当 | 品名 | 数量 | 急ぎ |
|---|---|---|---|---|
| 2026/10/06 | 佐藤 | ノート B5 | 3 | |
| 2026/10/07 | 鈴木 | 付箋 | 10 | 急ぎ |
1回目で見出しが書かれて2行目に、2回目は3行目に入りました。品名の前後の空白は Trim で取り除かれています。
手順3:フォームのコード(Initialize・登録・閉じる)
frmEntry のコード ウィンドウを開いて、次のコードを貼ります。
Option Explicit
' フォームが読み込まれたとき:選択肢を入れ、入力欄を初期の状態にする
Private Sub UserForm_Initialize()
cboPerson.AddItem "佐藤"
cboPerson.AddItem "鈴木"
cboPerson.AddItem "高橋"
ClearInputs
End Sub
' 登録ボタン:確かめる → 書く → 入力欄を空にする
Private Sub cmdRegister_Click()
Dim msg As String
Dim person As String
Dim r As Long
If cboPerson.ListIndex = -1 Then
person = ""
Else
person = cboPerson.Value
End If
msg = ValidateEntry(txtDate.Value, person, txtItem.Value, txtQty.Value)
If msg <> "" Then
lblMessage.Caption = msg
Exit Sub
End If
r = AppendEntry(ThisWorkbook.Worksheets(SHEET_NAME), txtDate.Value, person, _
txtItem.Value, txtQty.Value, chkUrgent.Value)
ClearInputs
lblMessage.Caption = r & " 行目に登録しました。"
txtItem.SetFocus
End Sub
' 閉じるボタン
Private Sub cmdClose_Click()
Unload Me
End Sub
' ×ボタン:入力途中の内容があるときは閉じずに知らせる
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu And HasInput() Then
Cancel = True
lblMessage.Caption = "入力途中の内容があります。[閉じる]ボタンで閉じてください。"
End If
End Sub
' 品名か数量に何か入っていれば True
Private Function HasInput() As Boolean
HasInput = (Trim(txtItem.Value) <> "" Or Trim(txtQty.Value) <> "")
End Function
' 入力欄を初期の状態に戻す
Private Sub ClearInputs()
txtDate.Value = Format(Date, "yyyy/mm/dd")
cboPerson.ListIndex = -1
txtItem.Value = ""
txtQty.Value = ""
chkUrgent.Value = False
lblMessage.Caption = ""
End Sub
シートは「注文一覧」という名前で用意しておきます。標準モジュールの ShowEntryForm を動かすと、フォームが表示されます。
コードの流れ
| 順 | 起きること | 動くプロシージャ | していること |
|---|---|---|---|
| 1 | ShowEntryForm を動かす | frmEntry.Show | 読み込まれていなければ自動で読み込まれ、表示される |
| 2 | フォームが読み込まれる | UserForm_Initialize | AddItem で担当の選択肢を入れ、ClearInputs で日付に今日を入れる |
| 3 | [登録]を押す | cmdRegister_Click | ValidateEntry で確かめる。メッセージが返れば Label に出して終える |
| 4 | 問題がなかった | AppendEntry | 最終行の次の行に書く |
| 5 | 書き終えた | ClearInputs、SetFocus | 入力欄を空にし、品名にカーソルを戻す。続けて次の1件を入力できる |
| 6 | [閉じる]を押す | cmdClose_Click | Unload Me でフォームを閉じる |
フォーム側のポイント
- AddItem は、リファレンスで「単一列のリスト ボックスやコンボ ボックスに項目を追加する」メソッドと説明されています。位置を省略すると、一覧の末尾に足されます。
- ListIndex は、何も選ばれていないとき -1 です。先頭の行が 0、次が 1 と続きます。担当が選ばれていないかどうかを、これで見分けています。
cboPerson.ListIndex = -1と代入すると、選択が外れます。 - Me は、コードが動いているそのフォーム自身を指すキーワードです。
Unload Meと書くと、フォームの名前を変えてもコードを直さずに済みます。 - 入力チェックのメッセージは Label に出しています。 メッセージ ボックスを閉じる操作がいらないので、続けて入力し直せます。
- SetFocus は、指定したコントロールにフォーカスを移すメソッドです。登録のあと品名に戻しておくと、続けて入力できます。
Unload と Hide の違い
| Unload | Hide | |
|---|---|---|
| 書き方 | Unload Me、Unload frmEntry |
Me.Hide、frmEntry.Hide |
| リファレンスの説明 | オブジェクトをメモリから取り除く | 画面から消え、Visible が False になる |
| 入力されていた値 | なくなる(もう一度読み込むまで、コードからも扱えない) | 残る(コントロールにはコードからアクセスできる) |
| もう一度 Show したとき | 読み込み直すので Initialize から始まる | 隠したときの状態のまま表示される |
| 向いている場面 | 入力が終わった、入力をやめた | フォームの値を標準モジュール側で使いたい、同じ内容でまた表示したい |
Hideで隠して、標準モジュール側で値を使う
「フォームで尋ねて、答えを呼び出し元で使う」形です。フォーム frmAsk に、テキストボックス txtName とボタン cmdOK がある想定です。
フォーム frmAsk 側:
Private Sub cmdOK_Click()
Me.Hide
End Sub
標準モジュール側:
Public Sub AskName()
frmAsk.Show ' モーダル表示。フォームが隠れるまで次の行へ進まない
Debug.Print frmAsk.txtName.Value ' Hide のあとも、コントロールの値を読める
Unload frmAsk ' 使い終わったら破棄する
End Sub
Show のリファレンスには、モーダルのフォームは「隠されるかアンロードされるまで、後続のコードは実行されない」と書かれています。Hide のリファレンスには、隠されたオブジェクトのコントロールは、動いているアプリケーションからプログラムで利用できると書かれています。この2つを組み合わせた書き方です。最後に Unload で破棄しておくと、次に Show したときに Initialize から始まります。
選び方の判断表
| 条件 | 選ぶもの |
|---|---|
| 入力をシートに書き終えた、または入力をやめた | Unload |
| フォームに入力された値を、呼び出し元のコードで読みたい | Hide(読み終えたら Unload) |
| 次に開いたときも、前の入力内容を見せたい | Hide |
| 次に開いたときは、まっさらな状態にしたい | Unload |
モーダルとモードレスの違い
Show メソッドの引数で、表示のしかたを選べます。
| モーダル | モードレス | |
|---|---|---|
| 書き方 | frmEntry.Show、frmEntry.Show vbModal |
frmEntry.Show vbModeless |
| 定数の値 | vbModal=1(既定) | vbModeless=0 |
| フォームを開いている間 | 応答するまで、アプリケーションのほかの部分を使えない | フォームを閉じずに、ほかのフォームやウィンドウを見られる |
| Show の次の行 | フォームが隠されるかアンロードされるまで実行されない | そのまま続けて実行される |
| プロパティでの指定 | ShowModal:True(既定) | ShowModal:False |
ShowModal プロパティは、プロパティ ウィンドウで設定します(実行時は読み取り専用)。Show の引数で指定しておくと、表示のしかたがコードから読み取れます。
選び方の判断表
| 条件 | 選ぶもの |
|---|---|
| 入力が終わるまで、ほかの操作を待ってほしい | モーダル |
| Show の次の行で、フォームの入力値を使う | モーダル |
| シートの内容を見比べながら入力してもらう | モードレス |
| フォームを出したまま、マクロの続きを進めたい | モードレス |
今回の登録フォームをモードレスにするには、ShowEntryForm の1行を変えます。
Public Sub ShowEntryForm()
frmEntry.Show vbModeless
End Sub
モードレスでは Show の次の行がすぐに動くので、「フォームの入力を待ってから続きの処理をする」コードは、フォーム側のボタンのイベントに書きます。 今回のコードは、登録の処理をすべて cmdRegister_Click の中で終えているので、どちらの表示でも同じように動く作りです。
QueryCloseで×ボタンを扱う
QueryClose は、フォームが閉じる前に起きるイベントです。引数の CloseMode で、何がきっかけで閉じようとしているかが分かります。
| 定数 | 値 | きっかけ |
|---|---|---|
| vbFormControlMenu | 0 | コントロール メニューの[閉じる](タイトル バーの×ボタン) |
| vbFormCode | 1 | コードから Unload ステートメントが呼ばれた |
| vbAppWindows | 2 | Windows のセッションが終わろうとしている |
| vbAppTaskManager | 3 | タスク マネージャーがアプリケーションを閉じようとしている |
Cancel に 0 以外の値を入れると、閉じる動きが止まります。
| やりたいこと | 書き方 |
|---|---|
| ×ボタンでは閉じないようにする | If CloseMode = vbFormControlMenu Then Cancel = True |
| 入力途中のときだけ止める | If CloseMode = vbFormControlMenu And HasInput() Then Cancel = True |
| コードからの Unload 以外をすべて止める | If CloseMode <> vbFormCode Then Cancel = True |
今回のフォームは2つ目の形です。品名か数量に何か入っているときだけ止めて、Label で知らせます。[閉じる]ボタンは Unload Me を呼ぶので CloseMode が vbFormCode になり、入力途中でも閉じられます。
×ボタンを止めるときは、閉じる手段を必ず1つ残します。 [閉じる]ボタンを置き、Cancel プロパティを True にして Esc キーでも選べるようにしておくと、操作に迷いません。
Initialize・Activate・QueryClose・Terminateの発生順
| 順 | イベント | 起きるタイミング(リファレンスの説明) | 書くことの例 |
|---|---|---|---|
| 1 | Initialize | オブジェクトが読み込まれたあと、表示される前 | 選択肢の追加、初期値の設定 |
| 2 | Activate | オブジェクトがアクティブなウィンドウになったとき | 表示のたびに行いたい更新 |
| 3 | QueryClose | UserForm が閉じる前 | ×ボタンの扱い、入力途中の確認 |
| 4 | Terminate | オブジェクトがアンロードされたあと、参照がすべてなくなったとき | 後始末 |
リファレンスから読み取れる注意点です。
- Initialize は「読み込み」のたびに起きます。 Unload したフォームをもう一度 Show すると、読み込み直しになるので Initialize から始まります。Hide で隠しただけのフォームは読み込まれたままです。
- Activate は、フォームが見えているときにだけ起きます。 Load で読み込んだだけのフォームは、Show するまで見えません。
- Activate と Deactivate は、同じアプリケーションの中でフォーカスが移ったときに起きます。 ほかのアプリケーションとの間でフォーカスが移っても起きません。また、アンロードのときに Deactivate は起きません。
- Terminate は、End ステートメントなどでアプリケーションが通常と違う終わり方をしたときには起きません。
選択肢の追加を Initialize に書いているのは、読み込みにつき1回だけ動くからです。Activate に AddItem を書くと、フォームがアクティブになるたびに同じ選択肢が足されていきます。
主要コントロールのプロパティ・イベント早見表
| コントロール | 用途 | 既定のプロパティ | 既定のイベント | よく使うもの |
|---|---|---|---|---|
| TextBox | 文字や数字の入力 | Value | Change | Value、SetFocus |
| ComboBox | 一覧から選ぶ、または打ち込む | Value | Change | AddItem、ListIndex、Style |
| ListBox | 一覧を常に見せて選ぶ | Value | Click | AddItem、ListIndex |
| CheckBox | はい・いいえの2択 | Value | Click | Value(True / False) |
| OptionButton | いくつかの中から1つ選ぶ | Value | Click | Value。同じ Frame の中では1つだけ選べる |
| CommandButton | 処理を始める・やめる | Value | Click | Caption、Cancel |
| Label | 説明の文字を表示する | Caption | Click | Caption |
- ComboBox と ListBox の使い分けは、リファレンスに目安があります。一覧を複数行いつも見せたいなら ListBox、場所を取らずに選ばせたいなら ComboBox です。
- 複数選択にした ListBox では、ListIndex ではなく Selected プロパティで選ばれた行を調べます(ListIndex のリファレンスの記載)。
- AddItem は、コントロールがデータに連結されているときは使えません(AddItem のリファレンスの記載)。
確かめて分かったこと
- IsDate は「10/6」や「2026-10-06」も日付として受け付けました。 確認環境では、どちらも CDate で 2026/10/06 になりました。年を省いた入力も通るので、入力の形をそろえたいときは、メッセージやラベルで「2026/10/06 の形」と例を見せておくと伝わりやすくなります。
- IsDate は「2026/2/30」を False にしました。 存在しない日付は、入力チェックの段階で止められます。
- 日付の文字列の解釈は、動かす環境の地域設定で変わりました。 同じ「2026/10/06」が、英語(米国)のロケールでは IsDate で False、日本語のロケールでは True でした。
- 「1.5」は IsNumeric を通ります。 整数だけを受け付けたいときは、
CDbl(qty) <> Int(CDbl(qty))のような確認を足す必要がありました。 - 見出しだけ・空のシートでも、End(xlUp).Row + 1 で2行目から書けました。 空のシートでは End(xlUp) が 1 を返すので、見出しを書いたあとに 2 行目へ進みます。
- 入力チェックを標準モジュールの関数にすると、フォームを開かずに11通りの入力をまとめて試せました。 条件を足したときの確かめ直しも、関数を呼ぶだけで済みます。
よくある質問
Q. ユーザーフォームとは? A. テキストボックスやボタンなどのコントロールを自分で並べて作る、入力用の画面です。Visual Basic Editor の[挿入]メニューから[ユーザーフォーム]で追加します。
Q. Unload と Hide の違いは? A. Unload はフォームをメモリから取り除き、Hide は画面から隠すだけで入力値を残します。入力が終わったら Unload、フォームの値をあとで読むなら Hide を使います。
Q. ユーザーフォームを表示したままシートを操作するには?
A. frmEntry.Show vbModeless でモードレス表示にします。既定はモーダルで、フォームに応答するまでほかの部分を使えません。
Q. ×ボタンで閉じられないようにするには? A. UserForm_QueryClose で、CloseMode が vbFormControlMenu のときに Cancel = True とします。閉じるためのボタンを別に用意して、Unload Me で閉じられるようにします。
Q. コンボボックスに選択肢を入れるには?
A. UserForm_Initialize の中で cboPerson.AddItem "佐藤" のように1件ずつ追加します。Initialize は読み込みにつき1回だけ動くので、選択肢が重なりません。
まとめ
- 流れは「Initialize で選択肢→登録ボタンで確かめる→最終行の次に書く→入力欄を空にする」 の4つです。
- 入力チェックと登録は標準モジュールの関数にすると、フォームを開かずに試せます。
- 閉じるなら Unload、値を残して隠すなら Hide です。Hide のあとも、コントロールの値はコードから読めます。
- モーダルは入力が終わるまで待つ表示、モードレスはほかのウィンドウも見られる表示です。
Show vbModelessで切り替えます。 - ×ボタンは QueryClose で扱えます。 CloseMode が vbFormControlMenu のときに Cancel = True で止められます。
- イベントは Initialize → Activate → QueryClose → Terminate の順です。選択肢の追加は Initialize に書きます。
- コンボボックスの未選択は ListIndex = -1 で見分けます。
参考・出典
- Microsoft Learn「Create a user form」 https://learn.microsoft.com/en-us/office/vba/excel/concepts/controls-dialogboxes-forms/create-a-user-form
- Microsoft Learn「UserForm object」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/userform-object
- Microsoft Learn「Show method」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/show-method
- Microsoft Learn「Hide method」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/hide-method
- Microsoft Learn「Load statement」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/load-statement
- Microsoft Learn「Unload statement」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/unload-statement
- Microsoft Learn「ShowModal property」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/showmodal-property
- Microsoft Learn「Initialize event」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/initialize-event
- Microsoft Learn「Activate, Deactivate events」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/activate-deactivate-events
- Microsoft Learn「QueryClose event」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/queryclose-event
- Microsoft Learn「Terminate event (Visual Basic for Applications)」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/terminate-event-visual-basic-for-applications
- Microsoft Learn「AddItem method (Microsoft Forms)」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/additem-method
- Microsoft Learn「ListIndex property」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/listindex-property
- Microsoft Learn「SetFocus method」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/setfocus-method
- Microsoft Learn「Style property」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/style-property
- Microsoft Learn「Cancel property (Microsoft Forms)」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/cancel-property-microsoft-forms
- Microsoft Learn「TextBox control」「ComboBox control」「ListBox control」「CheckBox control」「OptionButton control」「CommandButton control」「Label control」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/textbox-control ほか
- Microsoft Learn「Me keyword」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/me-keyword
- Microsoft Learn「IsDate function」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/isdate-function
- Microsoft Learn「IsNumeric function」 https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/isnumeric-function
(いずれも 2026-10-06 に確認)
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VBAユーザーフォームの作り方|入力・登録・閉じるまでコード付き」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。