コンボボックス
コンボボックスは、展開したリストから値を選択できるコントロールです。
リストには複数列の値を表示させることもできますが、最終的に表示されるのは1つの項目になります。

コンボボックスの概要
コンボボックスの使い方を理解するには、リストの設定と値の取得に注目しましょう。
リストの設定には、
・1つずつ追加していく(AddItem)
・リストで指定(List)
・セル範囲で指定(RowSource)
という3種類の方法があります。
値の取得は、TextプロパティとValueプロパティで取得できます。
変更後すぐに取得したい場合はChangeイベントで拾うと良いでしょう。
具体的な例を見ていきます。
サンプルコードの準備
ユーザーフォームも第7回ですので、慣れてきているかと思いますが、
復習も兼ねてサンプルコードを書くまでの流れを説明しておきます。
1.プロジェクトウインドウからで右クリックして「挿入」からユーザーフォームと標準モジュールを1つずつ追加しておきます。
2.標準モジュールは、ユーザーフォームの起動用のコードを書きます。
以下のコードを標準モジュールに追加して、シート上に貼り付けたコマンドボタンに割り当てておきます。
Sub macro()
UserForm1.Show
End Sub
3.ユーザーフォームには、今回の主役であるコンボボックスと、終了用にコマンドボタンを配置してください。
ユーザーフォームが表示されている状態でボタンを配置して、ボタンをダブルクリックするとこりっくした時のイベントプロシージャが追加されます。
コマンドボタンクリックには以下のようにユーザーフォームを閉じるコードを書いておきます。
Private Sub CommandButton1_Click()
Unload Me
End Sub
4.ユーザーフォームをモードレスに設定ます。
プロパティウインドウで、UserForm1を選択して、「ShowModal」の項目をFalseに変更します。

とりあえず、ここまででユーザーフォームを表示して閉じるまでが出来るようになります。

リストの設定方法
コンボボックスのリストの設定は、
・1つずつAddItemで追加する方法
・Listプロパティに配列を設定する方法
・RowSourceプロパティでセルの範囲を指定する方法
があります。
リストの設定は初期化(Initialize )のタイミングで行うのが一般的です。
UserForm1にInitializeプロシージャを追加します。
ユーザーフォームのコード画面から、上部のダウンリストから UserForm1 を選択し、右のダウンリストから Initialize を選択して追加します。

AddItemで設定
リストを1つずつ設定するには、AddItemを使用します。
Private Sub UserForm_Initialize()
Me.ComboBox1.AddItem "いちご"
Me.ComboBox1.AddItem "りんご"
Me.ComboBox1.AddItem "みかん"
End Sub
上記のように羅列しても構いませんが、Withステートメントで記述を省略する事もできます。
Private Sub UserForm_Initialize()
With Me.ComboBox1
.AddItem "いちご"
.AddItem "りんご"
.AddItem "みかん"
End With
End Sub
順番指定
AddItemでは、第2引数にリストの順番を指定する事もできます。
指定方法は、カンマにつづけて数値を書きますが、それまでのアイテム数より大きいとエラーとなります。
数値は0が一番上になります。 また、後から書いた方が優先されます。
Private Sub UserForm_Initialize()
With Me.ComboBox1
.AddItem "いちご", 0
.AddItem "りんご", 0
.AddItem "みかん", 1
End With
End Sub
上記の例では上から、りんご、みかん、いちごの順になります。
Listプロパティで設定
コンボボックスのListプロパティを使えば、リストを直接指定できます。
Private Sub UserForm_Initialize()
Dim arr(2) As String
arr(0) = "苺"
arr(1) = "林檎"
arr(2) = "蜜柑"
Me.ComboBox1.List = arr
End Sub
セルの範囲を指定したい場合は、配列の範囲(Range)を一旦変数で受けて配列にしてから代入します。
Sheet2 シートの A1:A3 に値がある場合の例です。
Private Sub UserForm_Initialize()
Dim lst
lst = Worksheets("Sheet2").Range("A1:A3")
Me.ComboBox1.List = lst
End Sub
RowSourceプロパティで設定
コンボボックスのプロパティであるRowSourceにセルの範囲を設定すれば、これをリストとして指定できます。
Sheet2 シートの A1:A3 にある値をリストとしたい時は、ComboBox1のプロパティウインドウの「RowSource」の項目に、「Sheet2!A1:A3」と入力します。
尚、この場合、Initializeなどにコンボボックスの設定コードを書くとエラーとなります。

同じ事をプログラムコードで書くときは、
Me.ComboBox1.RowSource = Worksheets("Sheet2").Range("A1:A3").Address(External:=True)
とします。 External:=True を指定しないと別のシートにリストがある場合上手くいきません。
選択された値を取得
選択された値の取得は、TextプロパティとValueプロパティで取得できます。
両者ともほぼ同じですが、選択されていない時の返り値が異なります。
Textプロパティでは空白
ValueプロパティではNULL
が返ります。空白とNULLは異なるので、判断処理を誤るとエラーとなります。
【注意】
私の環境(Excel2019 バージョン2212)では、Valueでも空白を返すようです。
他のサイトなどでは、NULLを返すという説明が大半です。
色々と調査しましたが不明でした。
ここでは、一応両方試した方が良いという結論にしておきます。
Private Sub TextButton_Click()
If Me.ComboBox1.Text = "" Then
MsgBox "値が空白です"
Else
MsgBox Me.ComboBox1.Text
End If
End Sub
Private Sub ValueButton_Click()
'Debug.Print Me.ComboBox1.Value
If IsNull(Me.ComboBox1.Value) Then
MsgBox "値がありません"
ElseIf Me.ComboBox1.Value = "" Then
MsgBox "値が空白です"
Else
MsgBox Me.ComboBox1.Value
End If
End Sub
選択された項目が何番目か?
値だけでなくリストの何番目を選択したかを得たい時は、ListIndexプロパティを使います。
1番上なら0が返り、選択されていない場合は‐1が返ってきます。
Private Sub TextButton_Click()
If Me.ComboBox1.Text = "" Then
MsgBox "値が空白です"
Else
MsgBox Me.ComboBox1.Text
End If
Debug.Print Me.ComboBox1.ListIndex
End Sub
値取得のタイミング
変更後すぐに取得したい場合はコンボボックスの Changeイベントで拾うと良いでしょう。
ユーザーフォームをモードレスにして動作を確認してみましょう。
ユーザーフォームのコード画面で、上部のドロップボックスからComboBox1、Changeを選択すると、イベントプロシージャが表示されます。
以下のプログラムでは、コンボボックスの値を変更するたびにセルに値を代入します。
Private Sub ComboBox1_Change()
Range("A1") = Me.ComboBox1.Text
End Sub
コンボボックスの動作を決めるプロパティ
コンボボックスでは、用意されたリスト以外にも、ユーザーが直接入力する事もできます。
リスト以外選択できないようにするには、Styleプロパティで設定します。
プロパティウインドウで設定
コンボボックスのプロパティウインドウの「Style」の項目で設定できます。

定数 | 値 | 内容 |
---|---|---|
fmStyleDropDownCombo | 0 | リスト以外に手入力で値を設定できます。(既定値) |
fmStyleDropDownList | 2 | リストからのみ値を設定できます。 |
プログラムコードで設定
プログラムコードで設定する場合は、初期化(Initialize)のタイミングで設定する事になるでしょう。
Initializeプロシージャで以下のように追加すればOKです。
Private Sub UserForm_Initialize()
Me.ComboBox1.Style = fmStyleDropDownList ’リストからのみ値を設定
End Sub
リストを複数列に設定
コンボボックスのリストで複数列を指定する場合は、
・列の数
・Textとして取得する列の設定
・Valueとして取得する列の設定
などを指定する必要があります。
以下のコードでは、Sheet2シートのA1:A3をリストに指定しています。
Textは1列目、Valueは2列目を指定していますので、それぞれ別々に値を取得する事ができます。
表示はTextプロパティで指定した値となります。
Private Sub UserForm_Initialize()
Dim myList
myList = Worksheets("Sheet2").Range("A1:B3")
With ComboBox1
.ColumnCount = 2 '表示列数の設定
.TextColumn = 1 'Textとして取得する列の設定
.BoundColumn = 2 'Valueとして取得する列の設定
.List = myList 'リストの設定
End With
End Sub

まとめ
コンボボックスの基本的な使い方を解説しました。
大まかな流れとしては、初期化(Initialize)のタイミングでリストを設定し、ユーザーが入力を終えたタイミングで値を取得します。
リストの設定は初心者のうちはAddItemがわかりやすいと思いますので得意技にしてしまいましょう。値の取得に関しては、Textプロパティで取得すればOKです。
更にリストからのみ値を得たい時はStyleプロパティを「fmStyleDropDownList」に設定するようにしましょう。
ユーザーフォームの使い方
・ユーザーフォームのプログラミング(準備編)
・ユーザーフォーム 第1回(起動と終了)
・ユーザーフォーム 第2回(ボタン)
・ユーザーフォーム 第3回(ラベル)
・ユーザーフォーム 第4回(テキストボックス)
・ユーザーフォーム 第5回(モーダル・モードレス)
・ユーザーフォーム 第6回(チェックボックス)
・ユーザーフォーム 第7回(オプションボタン)
・ユーザーフォーム 第8回(コンボボックス)
・ユーザーフォーム 第9回(リストボックス)
・ユーザーフォーム 第10回(リストボックス複数選択)
・ユーザーフォーム 第11回(タブストップ)
・ユーザーフォーム 第12回(スピンボタン)