ユーザーフォーム入門
リストボックス(ListBox)の追加

Excelマクロのユーザーフォームの基礎、エクセルVBAの入門解説
最終更新日:2022-11-17

第12回.リストボックス(ListBox)の追加


ユーザーフォーム入門として基礎から解説します。
リストボックスについて解説します。


リストボックスとコンボボックスの使い方はほぼ同様になります。
前回コンボボックスで単一列(1列)の場合を説明しましたので、今回は特に複数列について詳しく説明します。


リストボックスの追加

作成するリストは、都道府県を選択するリストにしてみます。
ラベルとリストボックスを追加します。

VBA マクロ ユーザーフォーム ListBox リストボックス

ラベル:lbl都道府県
リスト:lst都道府県


オブジェクト名は上記にしておきます。
リストに表示するのは、
都道府県コードと、都道府県名称の2列になります。


リストボックスのプロパィ

リストボックスに項目を追加するには、

Listプロパティ
Columnプロパティ
RowSourceプロパティ

いずれかを使用しますが、
一般的には、RowSourceプロパティかListプロパティが良いでしょう。

Worksheets("都道府県マスタ")

VBA マクロ ユーザーフォーム ListBox リストボックス

このデータをリストに追加します。


Listプロパティ

UserForm_Initializeに以下を追加

With Me.lst都道府県
  .ColumnCount = 2
  .List = Worksheets("都道府県マスタ").Range("A2:B48").Value
End With

.ColumnCount = 2
これが列数の指定です。
とりあえず、以下の2列表示されますね。

VBA マクロ ユーザーフォーム ListBox リストボックス

でも、列幅がちょっと変ですよね、コードの列は狭くしたいところです。
それには、ColumnWidthsプロパティを設定します。

With Me.lst都道府県
  .ColumnCount = 2
  .ColumnWidths = "30;80"
  .List = Worksheets("都道府県マスタ").Range("A2:B48").Value
End With

ColumnWidthsプロパティ
列幅を;(セミコロン)で区切って列ごとの幅をポイント単位で指定します。
幅に 0 が設定された列は表示されません。
ポイント以外の単位で指定する場合は、単位(in,cm)を明示してください。
数値は適宜修正して下さい。

.ColumnCountもColumnWidthsも、フォーム編集の画面でプロパティに直接入れても構いません。
ただし、プログラムの可読性や拡張性を考えると、コードで指定した方が良い場合が多いと思います。
また、
Worksheets("都道府県マスタ").Range("A2:B48").Value
これは2次元配列になります。
従って、2次元配列を変数定義しその配列にデータを入れてから、
Listプロパティに配列を指定しても同じ事になります。


Columnプロパティ

Listプロパティとほぼ同様ですが、行列(縦横)が反転します。

With Me.lst都道府県
  .ColumnCount = 2
  .Column = WorksheetFunction.Transpose(Worksheets("都道府県マスタ").Range("A2:B48").Value)
End With

このように、Transpose関数で行列を入れ替えればListプロパティと同様となります。
使われることはあまり無いと思います。


RowSourceプロパティ

With Me.lst都道府県
  .ColumnCount = 2
  .ColumnWidths = "30;80"
  .ColumnHeads = True
  .RowSource = Worksheets("都道府県マスタ").Range("A2:B48").Address(External:=True)
End With

.ColumnHeads = True
これは列見出しを表示する指定です。

ただし、このプロパティは、RowSourceを指定した場合にのみ有効となります。
Listプロパティを使用した場合は無効となります。
RowSourceに指定したセル範囲の1行上のセル値が、見出しとして表示されるようになります。

VBA マクロ ユーザーフォーム ListBox リストボックス

選択されたリスト項目の取得

変数 = Me.lst都道府県.Text
変数 = Me.lst都道府県.Value

上記では、どちらも都道府県コードが取得されます。
これは、
BoundColumnプロパティ
このプロパティが初期値の1になっているからです。

Textプロパティは1列目の値を取得します。
ValueプロパティはBoundColumnプロパティで指定された列の値を取得します。

BoundColumn = 2とした場合は、
Text:都道府県コード
Value:都道府県名
このように取得されます。

2列ならTextとValueを使い分けて、それぞれの列を取得できますが、3列以上の場合はどうするのでしょうか。

変数 = Me.lst都道府県.List(Me.lst都道府県.ListIndex, 0)
変数 = Me.lst都道府県.List(Me.lst都道府県.ListIndex, 1)

このように、Listプロパティの第2引数に列位置(0開始)を指定することで任意の列の値を取得できます。


リストボックスの複数選択

ここまでは、コンボボックスもほぼ同様の扱いになります。
では、ここからはリストボックスならではの問題に入ります。

リストボックスでは、複数選択が必要な場合があります。
今回の例では、都道府県なので、実際には複数選択の必要はありませんが、
例として、複数選択した場合として説明しておきます。
複数選択にはMultiSelectプロパティを指定します。

MultiSelectプロパティの設定値
定数 内容
fmMultiSelectSingle 0 項目は 1 つだけ選択できます (既定値)。
fmMultiSelectMult 1 複数選択を許可します。
項目の選択/選択解除を行うには、Space キーを押すか、またはクリックします。
fmMultiSelectExtended 2 複数選択を許可します。
Shift キーを押しながらクリックするか、または Shift キーを押しながら方向キーを押すと、現在選択されている項目を始点として一連の項目を連続的に選択できます。
項目の選択/選択解除を個別に行うには、Ctrl キーを押しながらクリックします。

これで簡単に複数選択可能になります。
問題は、複数選択した場合の、複数の選択値の取得や、選択を全て一括で解除したりする場合です。

複数選択されたリスト項目の取得
Dim i As Integer
With Me.lst都道府県
  For i = 0 To .ListCount - 1
    If .Selected(i) = True Then
      変数 = .List(i)
      Exit For
    End If
  Next
End With

ListCountでリストの件数を取得し、Selectedで選択の有無を判定し、Listで選択値を取得します。
複数列の場合は、List(i, 列位置)となります。

リストを全て選択したり、全て解除したりするVBAサンプル
Private Sub リスト全選択解除(ByVal blnSel As Boolean)
  Dim i As Integer
  With Me.lst都道府県
    For i = 0 To .ListCount - 1
      .Selected(i) = blnSel
    Next
  End With
End Sub

Call リスト全選択解除(True)とすれば全選択されます。
Call リスト全選択解除(False)とすれば全解除されます。


IntegralHeightプロパティ

ListBox(またはTextBox)がリスト内のテキストの完全な行を表示するか、部分的な行を表示するかどうかを示します。
つまりリスト内のテキストによってリストの高さを調整するかどうかです。
TRUEの場合、高さ調整を自動で行いテキストの完全な行を表示します。
FALSEの場合、高さを調整を行わないので最終行の表示が切れる場合があります。

IntegralHeight = Teue
VBA マクロ ユーザーフォーム ListBox リストボックス
IntegralHeight = False
VBA マクロ ユーザーフォーム ListBox リストボックス

デフォルトでは、IntegralHeight = Teue になっています。
通常はこのままで良いのですが、リストボックスの高さが自動調整されるのが困る場合もでてきます。
そこで、IntegralHeight = False にしたくなります。
しかしFalseにしてしまうと、最終行が不完全な表示になってしまう場合がててくるので、これはこれで困ります。
IntegralHeight = False の場合の最終行対策としては、
リストの最後にダミーデータを入れ、そして最終行は選択できないようにする方法があります。
以下は、最終の選択を出来ないようにするVBAサンプルです。

Private Sub ListBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
  If Me.ListBox1.ListIndex = Me.ListBox1.ListCount - 1 Then '最終行の判定
    Me.ListBox1.ListIndex = -1 '選択行を無しにする
    Cancel = True 'イベントをキャンセルする
  End If
End Sub

イベントをキャンセルできるBeforeUpdateを使います。
VBA各行の意味合いはコメントに書きました。




同じテーマ「ユーザーフォーム入門」の記事

第9回.標準モジュールとフォーム間のデータ受け渡しⅠ
第10回.標準モジュールとフォーム間のデータ受け渡しⅡ
第11回.コンボボックス(ComboBox)の追加
第12回.リストボックス(ListBox)の追加
第13回.チェックボックス(CheckBox)の追加
第14回.オプションボタン(OptionButton)の追加
第15回.ここまでの整理と全VBA
第16回.アクティブコントロールに色を付ける
第17回.Enterキーで次のコントロールに移動する
第18回.2段階のコンボボックス
第19回.数値専用のテキストボックス


新着記事NEW ・・・新着記事一覧を見る

文字列のプロパティ名でオブジェクトを操作する方法|VBA技術解説(2022-12-14)
数字(1~50)を丸付き数字に変換するVBA|VBA技術解説(2022-11-15)
TEXTAFTER関数(テキストの指定文字列より後ろの部分を返す)|エクセル入門(2022-11-14)
TEXTBEFORE関数(テキストの指定文字列より前の部分を返す)|エクセル入門(2022-11-14)
TEXTSPLIT関数(列と行の区切り記号で文字列を分割)|エクセル入門(2022-11-12)
LAMBDA以降の新関数はVBAで使えるか|VBA技術解説(2022-11-11)
WRAPCOLS関数(1次元配列を指定数の列で折り返す)|エクセル入門(2022-11-08)
WRAPROWS関数(1次元配列を指定数の行で折り返す)|エクセル入門(2022-11-08)
EXPAND関数(配列を指定された行と列に拡張する)|エクセル入門(2022-11-07)
TAKE関数(配列の先頭/末尾から指定行/列数を取得)|エクセル入門(2022-11-06)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.並べ替え(Sort)|VBA入門
8.エクセルVBAでのシート指定方法|VBA技術解説
9.マクロって何?VBAって何?|VBA入門
10.繰り返し処理(Do Loop)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ