こんにちは、Ryoです。
VBAで扱うユーザーフォームにリストボックス(ListBox)がありますが、リスト化された項目を複数まとめて選択/処理したいなーと思うことがありますよね。その場合はMultiSelectプロパティを使用することで可能になりますので、久々の更新ですがサンプルを交えて書いていこうと思います。
1.サンプル概要
ユーザーフォーム(UserForm1)にリストボックス(ListBox1)とコマンドボタン(CommandButton1)を配置し、サンプル文字を表示させています。

このリストボックスに表示された項目に対し、例として”Sample1,Sample3,Sample5″を選択してコマンドボタンを押すと、メッセージボックスに表示されるものです。

2.ユーザーフォーム構成
今回のサンプルとして使用したUserForm構成は以下の通りになります。
CommandButtonの表記文字は規定の「CommandButton1」のままでも特に問題ありませんので、ここはお好みで良いと思います。

3.サンプルコード
◆UserForm初期化時の処理
先ず何をするかと言いますと、ユーザーフォームが表示される際にリスト化する項目を読み込んで、最初からリストボックスに表示させた状態にする処理を行います。
Private Sub UserForm_Initialize()
Dim i As Integer
With ListBox1
For i = 1 To 10
'ListBoxにSample1~10を表示
.AddItem "Sample" & i
Next i
'ListBox先頭の見出し文字
.AddItem "「複数項目の選択サンプル」", 0
'クリック又はSpaceキーで選択/解除
'.MultiSelect = fmMultiSelectMulti
.MultiSelect = fmMultiSelectExtended
End With
'*****************************
'「MultiSelectプロパティ」
'.fmMultiSelectSingle⇒1項目のみ選択(規定)
'.fmMultiSelectExtended⇒Shiftキー + 方向キー、又は
' クリック+ドラッグし、範囲選択
' Cttrlキー + クリックで個別選択
'*****************************
End Sub
リストボックスに表示させるデータは、AddItemメソッドを使用してリストボックスに項目を追加しています。
構文:オブジェクト.AddItem item,varindex
引数itemは追加したい項目、varindexは項目追加の行を指定しますが省略も可能です。その場合は末尾に追加される形になります。因みにvarindexに「0」を指定すると先頭になりますので、サンプル中では見出しにしたい項目に「0」を指定しています。
次に、本題の複数選択を可能にするMultiSelectプロパティです。
構文:オブジェクト.MultiSelect = 定数の指定
サンプルコード中にも書いていますが、指定する定数は3種類あります。
| 定数 | 内容 |
| fmMultiSelectSingle | 既定値(1個のみ選択可) |
| fmMultiSelectMulti | クリック、又はSpaceキーにて項目を複数選択可(解除も同様) |
| fmMultiSelectExtended | Shiftキーを押しながらクリックして連続範囲選択、Ctrlキーを押しながらクリックして個別に複数選択が可能 |
複数選択する場合は「fmMultiSelectMulti」、又は「fmMultiSelectExtended」になりますが、個人的には総合的に使いやすい「fmMultiSelectExtended」がお薦めです。
◆選択項目の取得(コマンドボタン処理)
ここでは先程選択したリストボックスの複数項目を取得し、メッセージボックスにて表示する処理を行います。
Private Sub CommandButton1_Click()
Dim Sample_Str As String
Dim i As Integer
With ListBox1
'ListBoxの項目数分繰り返す
For i = 0 To .ListCount - 1
'項目の選択有無を判定
If .Selected(i) Then
'選択されている項目を取得する
Sample_Str = Sample_Str & .List(i) & vbCrLf
End If
Next i
'取得した項目をメッセージボックスで表示
MsgBox "「選択した項目は以下です」" & vbCrLf & Sample_Str
End With
End Sub
選択有無を判定する上で、先ずリストボックスに表示されている数を取得する必要がありますので、そこは「ListCountプロパティ」を使用すれば登録数を返してくれます。
For文で繰り返し処理を行う際に気を付ける点は、リストに表示されている項目のインデックス番号は「0」から始まっています。従ってi=0として行う必要がありますので、繰り返し回数はListCount-1となります。
次に選択有無の判定ですが、リストボックスで選択されている項目は「Selectedプロパティ=True」になりますので、それを用いて行います。
また、リスト項目データは配列で管理されている為、「Listプロパティ」を使用して取得しますから.List(i)とすることで選択された項目データを取得しています。本サンプルの場合は以下表のような形になっています。
| ListBox表示項目 | Index番号 |
| 「複数項目の選択サンプル」 | ListBox1.List(0) |
| Sample1 | ListBox1.List(1) |
| Sample2 | ListBox1.List(2) |
| Sample3 | ListBox1.List(3) |
| Sample4 | ListBox1.List(4) |
| Sample5 | ListBox1.List(5) |
| Sample6 | ListBox1.List(6) |
| Sample7 | ListBox1.List(7) |
| Sample8 | ListBox1.List(8) |
| Sample9 | ListBox1.List(9) |
| Sample10 | ListBox1.List(10) |
後は繰り返し処理を行いながら、変数Sample_Strに取得データを改行しながら書込みを行い、最終的にメッセージボックスで表示する流れになります。
◆参考:リスト項目をセルから取得したい場合
実際に使用する場合、Excelシート上から項目データを読み込んでリスト化する形が多いかと思いますので、その場合のサンプルは以下になります。
例えば、セルA1~A11に同様の項目があり、それを取得してリスト化する場合のUserForm_Initialize()は次の通りです。

Private Sub UserForm_Initialize()
'セル上のデータを取得しリスト化する場合
Dim i As Integer
With ListBox1
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
.AddItem Cells(i, 1)
Next i
.MultiSelect = fmMultiSelectExtended
End With
End Sub
このサンプルで動作しても同様の結果になると思います。
4.まとめ
ユーザーフォームの中でも使用頻度が高いリストボックスですが、運用を考えた場合に1項目のみ選択して都度処理を行うのは手間がかかってしまうので、複数選択して処理できる手段をしっておくと大変便利です。
またMultiSelectプロパティで動作を切り替えることも出来ますから、環境に応じて使い分けることも可能ですので何か機会があればぜひご活用くださいませ!
以上、リストボックスで複数の項目を選択する方法についてでした。今回の記事が何かの参考になれば幸いです。
Ryo

