ユーザーフォーム 第8回

ユーザーフォーム

コンボボックス

 コンボボックスは、展開したリストから値を選択できるコントロールです。
 リストには複数列の値を表示させることもできますが、最終的に表示されるのは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」の項目で設定できます。

定数内容
fmStyleDropDownCombo0リスト以外に手入力で値を設定できます。(既定値)
fmStyleDropDownList2リストからのみ値を設定できます。

プログラムコードで設定

 プログラムコードで設定する場合は、初期化(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」に設定するようにしましょう。

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