VBA UserForm 複数列のリストボックス設定・取得方法

スポンサーリンク

UserForm 「リストボックス」の解説です。前回設置したマルチページコントロールのページに「リストボックス」を設置して、シートのセル範囲に保存しているパスワード生成の設定データをユーザーフォームに表示させて活用する方法を紹介します。

くるみこ
くるみこ

それでは今回はお約束どおり「リストボックス」を設置して利用する方法を勉強したいと思います(^^)

「リストボックス」って「コンボボックス」の拡大版って感じですか?
初めて聞きました! よろしくお願いしますm(__)m

【この記事でわかること
・「リストボックス」の設置方法とデータの設定方法がわかります
「リストボックス」のリストからデータを取得する方法がわかります

前回記事のおさらいは、下のカードをクリックすれば開きます(^^ゞ

くるみこ
くるみこ

前回記事では「マルチページ」を設置する方法と注意点について解説・勉強しています。是非覗いてみてね(^^)/

スポンサーリンク

「リストボックス」を設置・設定します

・必要に応じてプロパティなどを確認しながら、早速「リストボックス」を設置していきます。

「マルチページ」に配置します

・今回は位置する場所は「マルチページ」の二つ目の「ページ」に配置します。
・ツールボックスから「リストボックス」をクリックします。
・配置したい箇所でクリック&ドラッグして任意の位置、大きさで配置します。

・配置するだけなら簡単ですね。

「リストボックス」にデータ表示の準備をします

・表示させたいデータは「これ」PW生成の設定データです。

「リストボックス」のプロパティを設定します

・今回設定するプロパティは次の5つです。

ColumnCount プロパティ

・「リストボックス」に表示する列の数を設定します。(既定値は1)
・複数列表示する場合にここの値を設定する必要があります。
・今回の必要列数は、セル範囲が8列あるので「8」に設定する必要があります。

ColumunHeads プロパティ

・リストに列見出しを表示するかしないかを設定します。
・既定値は False = 表示しません。
・表示させる場合は True を設定します。

ColumnWidths プロパティ

・列幅設定用のプロパティです。
・各列の幅をポイント単位(既定)または、指定した単位(cmなど)で設定します。
・複数列の指定は、「;」セミコロンで区切ります。
・「0」を指定した場合はその列は非表示となります。
・未設定(空白)の場合は既定の列幅で表示されます。

RowSource プロパティ

・「リストボックス」のリストとして表示させるセル範囲の Address を指定します。
ColumunHeads プロパティが True 設定の場合は、見出しも含めて範囲設定します。
・今回使用する設定はこれです。

List プロパティ

・「リストボックス」項目の「値」の設定と取得ができます。

【設定構文】object. List (row,column) = Variant
【取得構文】object. List (row,column)

【パーツ説明】
 object 必須です。 有効なオブジェクトを指定します。
 row 必須です。 0 から始まり、リストの最大行数より 1 小さい値までの範囲の整数です。
 column 必須です。 0 から列数より 1 小さい値までの範囲の整数です。
 Variant 省略可能です。 設定の際に設定する「」を指定します。

・リストはバリアント型の配列なのでリスト内の各項目には行番号と列番号が含まれています。

VBAで「リストボックス」を設定する

・設定が必要なするプロパティがわかったので、VBAで設定していきます。
・「リストボックス」のあるページが表示されるタイミングで動作する必要があります。
VBAコードを記載する場所は「MultiPage1_Change」イベントです

'マルチページのChangeイベント
Private Sub MultiPage1_Change()
    Dim eRow As Long    '最終行用
    Dim LData As Range  'セル範囲指定用
    If MultiPage1.Value = 1 Then
        With Worksheets("設定値")
            eRow = .Cells(Rows.Count, 2).End(xlUp).Row
            Set LData = .Range(.Cells(2, 1), .Cells(eRow, 8))
        End With
        With ListBox1
            .ColumnCount = 8
            .ColumnHeads = True
            .ColumnWidths = "60;60;60;60;20;20;40"
            .RowSource = LData.Address
        End With
    End If
End Sub

MultiPageValue は 「Page」のインデックスを表しています。
一番左側が「0」以降「1」「2」「3」….と続きます
・ここでは、「リストボックス」があるページは2番目ですので「1」です。

・5行目、Changeイベント発生時のマルチページの Value が「1」の場合以降を処理します。
・7行目で、セル範囲の最終行を取得して変数 eRow に代入しています。
・8行目は、Rangeオブジェクト変数 LData にセル範囲をセットしています。
・11行目、リストの列数を設定しています。
・12行目、リストの列見出しを表示するよう True に設定しています。
・13行目、各列の列幅を設定しています。
・14行目、リストとして表示させるセル範囲の Address を設定しています。

List が表示されるようになったGIF画像です。

「リストボックス」から選択したリストを取得する

・取得開始をどうするか検討しました。(コマンドボタン設置など)
・検討した結果、ListBox1_DblClick イベントにコードを記述することとしました。
・選択リスト行をダブルクリックした場合のイベントです。

Option Explicit
Dim LData As Boolean    'モジュールレベルの変数宣言
'リスト行でダブルクリック時の発生イベント
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
    With ListBox1
        If .ListIndex = -1 Then
            MsgBox "リストが未選択です!"
        Else
            LData = True    'モジュールレベル変数をTrueに
            MultiPage1.Value = 0
            '分類
            Cmb1.Text = .List(.ListIndex, 0)
            'ID
            Cmb3.Text = .List(.ListIndex, 2)
            'mKey
            Cmb4.Text = .List(.ListIndex, 3)
            'L
            TxtBox0.Text = .List(.ListIndex, 4)
            'R
            TxtBox1.Text = .List(.ListIndex, 5)
            SpinB1.Value = TxtBox1.Value 'スピンボタンの値を初期化
            '文字数
            TxtBox2.Value = Val(TxtBox1.Value) _
                            - Val(TxtBox0.Value) + 1
            '名称
            Cmb2.Text = .List(.ListIndex, 1)
            'Option設定を反映させる
            Select Case .List(.ListIndex, 6)
                Case OptB1.Caption: OptB1.Value = True '任意
                Case OptB2.Caption: OptB2.Value = True '指定
                Case OptB3.Caption: OptB3.Value = True '禁止
            End Select
            LData = False   'モジュールレベル変数をFlseに戻す
        End If
    End With
End Sub

・2行目、モジュールレベルで Boolean 型の変数 LData を宣言しています。
・これは、各値代入時にイベントが発生してしまうので無駄な処理の回避に使用します。
・9行目で、LData = Trueに設定しています。
・10行目の、MultiPage1.Value = 0 で Page を「設定シート」に切替ています。
・11行目以降で、「設定シート」の各項目に選択しているリストのデータを代入しています。
・33行目で、LData = False に戻しています。

・特にイベント発生時の処理を回避したかったのが、Cmb2_Change でした。

'テキスト部の文字列を重複せずにItemに登録
Private Sub Cmb2_Change()
    Dim i As Long       'ループカウンター用
    Dim c As Long       'HIT列保存用
    Dim flg As Long     '重複チェック用フラグ
    Dim strSet As String, strC() As String
    Dim eRow As Long
    Dim rng1 As Range, rng2 As Range
    strSet = Cmb2.Text
    If strSet = "" Then Exit Sub
    If LData = True Then Exit Sub 'ListBoxDblClickの場合抜ける
    With Worksheets("設定値")
<以下省略>

11行目の If LData = True Then Exit Sub で、ListBox1_DblClick から呼び出されている場合は以降の処理を実行せずに抜けるように設定しています
・こうしておかないと、リストから設定実行しているのに、重複リストがあるかどうかチェックしたり、重複している場合にデータ選択のダイアログが表示されてしまします。
・これで余計な動作を回避できるようになりました。

・「リストボックス」の設定・取得が出来るようになったので今回はここで終了とします。

スポンサーリンク

まとめ(おわりに)

・いかがでしたでしょうか?
・今回も、記事内で使用したコードのサンプルファイルを登録していますのでご利用ください。
今までの記事のサンプルも登録していますのでよろしければお使いください(^^)

まとめと感想など

くるみこ
くるみこ

「リストボックス」の利用方法でした。VBAでリストを設定する方法やリストを取得して利用する方法までを解説・勉強しました。この方法ならリストが全部見えているので選択しやすいですよね!

保存されているリストならすでに重複チェックされているからそのまま使えるということですね。ビジュアル的にもすごくかっこいいし便利ですね(^^♪

くるみこ
くるみこ

「リストボックス」で気になるのが、列幅の設定と行の区切りが無い点なんですよね(^^; 次回は「リストビュー」を利用できないか検討してみましょう! 次回も楽しみにしていてね(^^)/

【今回わかったことは】
・「マルチページ」の設置方法と「タブストリップ」との違いがわかりました
・「マルチページ」を後から追加設置する方法がわかりました
・VBAでコントロールを追加設置する場合の注意点がわかりました

今後の記事について

今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
「汎用でだれでも使えて活用できるように考えてVBAを使う」というポリシーで、記事を継続して書いていきたいと思っています。どうぞよろしくお願いしますm(_ _)m

【検討中の今後の記事内容は・・・・・】
・実務に役立つものを提供できるよう常に検討しています(^^ゞ
・その他雑記的に「プチネタなど」もいろいろ考えていきたいと思います・・・・・
・今後の記事にもご期待ください(^^)/

記事のサンプルファイルをダウンロードできます

今回の記事のサンプルをダウンロードできるようにしています
過去の記事で使用したサンプルファイルがダウンロードできるページを設置しています
こちら(このリンク先)からご利用ください