TL;DR —
ComboBoxはドロップダウンです。項目を一つ選ぶか、(既定では)自分で入力します。ComboBox1.List = Range("A2:A50").Valueで埋めます。二つの問いに同時に答えます —.ListIndexによる どの項目か(0 始まり、テキストがリストにないときは-1)と、.Valueによる どんなテキストか です。 落とし穴:.Value <> ""はボックスが空でないことを示すだけで、ユーザーが本物の項目を選んだことは示しません。 リストからの正しい選択が必要なら.ListIndex >= 0を調べるか、.Style = fmStyleDropDownListで入力を禁じます。
' ComboBox の選択を読む - 必ずリストから選ばせる
Private Sub cmdOK_Click()
If ComboBox1.ListIndex = -1 Then
MsgBox "Please choose an item from the list."
Exit Sub
End If
MsgBox "You chose " & ComboBox1.Value ' リストに裏付けられた本物の選択
End Sub
ComboBox は UserForm 上のコントロールで、ほかのどのコントロールとも同じ規則に従いま
す。選択はボックスそのものからではなく、プロパティを通して読む のです。ListBox
との違いは、ComboBox が一行を表示し、入力も受け付けられることです — まさにそこに、おもしろいバグが潜んでい
ます。
この記事で学べること
ComboBoxが一行に畳まれたListBoxである理由、そしてほぼ同じように読めること.List = Range.Valueで一気に埋める、あるいは計算した項目には.AddItemを使う- 答える二つの問い:どの行か(
.ListIndex)と どんなテキストか(.Value) .Styleプロパティ —fmStyleDropDownComboは入力を許し、fmStyleDropDownListは許さない- 最大の落とし穴:
.Value <> ""は正しい選択ではない。.ListIndex >= 0を調べる ComboBoxが正しいコントロールになるのはいつで、ListBoxのほうが合うのはいつか
考え方の軸:入力もできる、一行の ListBox
ComboBox は、ドロップ矢印の付いた一行に畳んだ ListBox です。埋め方は同じ、読み方も
同じ二つのプロパティ — ですが自由入力も受け付けられるので、常に二つの問いに同時に答えます。
ComboBox1.ListIndex ' どの行が選ばれているか(0 始まり、-1 = テキストがリストにない)
ComboBox1.Value ' ボックスにあるテキストの中身(リストの項目、または入力された文字列)
この二つを分けて持てば、コントロールは腑に落ちます。.Value は ボックスが言っている中身 です。.ListIndex
は それがリストから来たかどうか です。ユーザーがドロップダウンから選べば、両者は一致します。ユーザーが新しい
ものを入力すると、.Value は入力されたテキストを保ち、.ListIndex は -1 になります — テキストがリストの項
目ではないという合図です。
ComboBox を埋める
埋め方は ListBox とまったく同じです。列全体を一度に代入する、これが速い道です。
Private Sub UserForm_Initialize()
ComboBox1.List = Sheet1.Range("A2:A50").Value ' 一列から一度で埋める
End Sub
Range.Value は 2 次元配列で .List はそれを受け取るので、一行でドロップダウンを読み込めます
(VBA Range を参照)。.AddItem は一つずつ組み立てる項目のときだけ使います。
Dim i As Long
For i = 1 To 12
ComboBox1.AddItem "Month " & i ' 計算した項目を一つずつ追加する
Next i
埋め直す前に空にするには ComboBox1.Clear を呼びます。最初から既定値を表示させたいなら、埋めたあとに
.ListIndex = 0 にするか、既知の項目を .Value に代入します。
Style:ユーザーが入力してよいかを決める
これは、人が見落とすプロパティです。ComboBox には、その性格全体を左右する .Style があります。
ComboBox1.Style = fmStyleDropDownCombo ' 既定:リストから選ぶ、または自分で入力する
ComboBox1.Style = fmStyleDropDownList ' ロック:ユーザーはリストの項目しか選べない
fmStyleDropDownCombo が既定で — ユーザーは何でも入力できます。fmStyleDropDownList は ComboBox を厳格な
選択器に変えます。入力は一致する項目へジャンプするだけで、最終的な値は常にあなたの用意したものです。フォームが
自由入力を受け付けてはいけないなら、.Style を設定しましょう — あとから検証で追い払おうとしてはいけません。
最大の落とし穴:空でないボックスは正しい選択ではない
不正なデータを通してしまうバグがこれです。既定のスタイルでは、ユーザーはリストにない値を入力できます。ボックス が空でないことしか確かめないコードは、打ち間違いも平気で受け入れてしまいます。
' WRONG - accepts anything the user typed
If ComboBox1.Value <> "" Then ProcessOrder ComboBox1.Value
' RIGHT - insist the choice came from the list
If ComboBox1.ListIndex >= 0 Then
ProcessOrder ComboBox1.Value
Else
MsgBox "Please choose an item from the list, not free text."
End If
.Value <> "" が示すのは、ボックスに 何か があることだけです。.ListIndex >= 0 は、ユーザーが実際のリスト
項目を選んだことを示します — テキストが選ばれたのではなく入力されたときは、いつでも .ListIndex が -1 だか
らです。規則は単純です。リストからの正しい選択が大事なときは、.Value <> "" ではなく .ListIndex を調べる
のです。自由入力がそもそも一切あってはならないなら、より上流のきれいな直し方があります — .Style = fmStyleDropDownList に設定すれば、落とし穴は起こりえません。(ボックスがフォーカスを失ったときに一致しない入
力を拒む .MatchRequired プロパティもありますが、.Style を設定するほうが無骨でも確実な道具です。)
Value と Text、そして変化への反応
ComboBox では、.Value と .Text はたいてい同じ文字列を読みます。あなたが使うのは .Value です。.Text
が効くのは、入力が確定する前に 入力中に表示されているもの を気にするときです。ユーザーが選択を変えた瞬間に反
応するには、Change イベントを扱います。
Private Sub ComboBox1_Change()
' キー入力のたび、選択のたびに発火する - 軽く保つ
Label1.Caption = "Current: " & ComboBox1.Value
End Sub
入力できる ComboBox では Change がキー入力のたびに発火するので、そのハンドラーは軽く保ちます — 一文字ごと
にデータベース検索を走らせてはいけません。
ComboBox か ListBox か:スペースと選択数で決める
ComboBox と ListBox は埋め方と読み取りのプロパティを共有するので、選択がどう振る舞
うべきかで選びます。答えが 単一の値 で、スペースが限られていて、畳まれたドロップダウンのほうがすっきりする
とき — あるいは自由入力を 許したい とき — は ComboBox を使います。選択肢が 一目で見えている べき、ある
いはユーザーが 複数 を選ぶかもしれないときは ListBox を使います。複数選択は ListBox だけの機能です。
ComboBox は決して複数の項目を返せません。
ExcelMaster の活用
ここでの静かな失敗は、コードが .ListIndex >= 0 ではなく .Value <> "" を確かめたせいで、ユーザーの入力を何
でも受け入れてしまう ComboBox です — つづりを間違えた製品名が、そのままあなたのデータに流れ込みます。
ExcelMaster には、コントロールを普通の言
葉で伝えられます — 「ユーザーが必ず選ぶ製品コードのドロップダウン、自由入力はなし」 — すると正しい .Style を
設定し、あなたのデータから一覧を埋め、.ListIndex を調べて選択を読むので、本物の選択だけが通ります。ブックと
コードはあなたの手元に残ります。
よくある質問
VBA で範囲から ComboBox を埋めるには?
範囲を一文で .List に代入します。ComboBox1.List = Sheet1.Range("A2:A50").Value です。Range.Value は
2 次元配列で .List はそれを受け取るので、これで列全体を一度に読み込めます。.AddItem は一つずつ組み立てる項
目のときだけ使い、すでに行のあるボックスを埋め直す前に .Clear を呼びます。
VBA の ComboBox から選択された値を取得するには?
現在の入力のテキストは .Value で、それが来た 0 始まりの行は .ListIndex で読みます。テキストがリストから選
ばれたのではなく入力されたとき .ListIndex は -1 なので、本物のリスト選択が必要なら、.Value に対して動く
前に .ListIndex >= 0 を調べます。
ComboBox でユーザーが自由入力するのを止めるには?
ComboBox1.Style = fmStyleDropDownList を設定します。これでコントロールはリストの項目だけにロックされます —
入力は一致する項目へジャンプするだけで、最終的な値は常にあなたの用意したものです。既定の
fmStyleDropDownCombo は自由入力を許すので、それを保つときは .ListIndex >= 0 での検証が大事になります。
ComboBox で ListIndex = -1 は何を意味しますか?
現在のテキストがリストの項目のどれでもない、という意味です — ボックスが空か、ユーザーが一致しない何かを入力し
たかです。ドロップダウンからの正しい選択は常に 0 以上の .ListIndex を返すので、.ListIndex = -1 は入力を
拒むか、もう一度うながすための合図です。
ComboBox と ListBox の違いは何ですか?
ComboBox はドロップダウン付きの一行を表示し、単一の値を返し、自由入力を許せます。
ListBox は複数の行を一度に表示し、複数選択を許せます。コンパクトな単一の選択には
ComboBox、選択肢が見えているべき、あるいはユーザーが複数を選ぶときは ListBox を選びましょう。
検証環境
検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-09-25。
関連ガイド: VBA ListBox · VBA CheckBox · VBA UserForm · VBA Range · VBA InputBox
