B-01 セルの入力値に応じた候補リストを作成・表示(ComboBox)2022.05.17
次の書籍の第1章~5章を公開しています。
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」
「セルに入力した単語を、データベースから検索し、該当するデータを候補リストとして選択できるようにしたい」といったことはないでしょうか。
今回は、セルに入力した値に応じて候補リストが表示されるフォームを作成します。
コンボボックスの実践応用サンプルです。
リストボックスのバージョンとは異なり、マウス操作で候補を選ぶ仕様にしています。
【例】セルに「マゼンタ」と入力すると データベースから「マゼンタ」を含むデータを抽出しリスト表示する
【動画】
・セルに入力した値が含まれる商品名のリストを作成
・リストを選択すると対象セルの一つ左のセル(B列)に商品コードが入力される
(D列・E列はB列のコードを参照し商品名・サイズを表示する数式が入力されています)
このような動作の実現にはいくつかの方法が考えられますが、最も簡単だと思われる方法で実装します。
サンプルファイル ダウンロード
準備 1
シートを2枚準備します。
■「入力・検索用」シート
B列に商品コードを入力すると、D列に商品名、E列にサイズが表示されるように数式を設定します。C列は検索欄として使用します。
■「データ」シート
データベース用のシートです。
準備 2
ユーザーフォームを挿入し、次のコントロールを追加します。
■ComboBoxコントロール
役割:リスト表示
オブジェクト名:ComboBox1
個数:1
Style:2 - fmStyleDropDownList ※
※ Styleプロパティをリスト設定にするとリスト選択のみ可能となり キー操作は受け付けません
■ComboBoxコントロール
役割:フォームを閉じる
オブジェクト名:CommandButton1
個数:1
Default:True ※
※ [Enter]キーを押すとボタンがクリックされる設定です
サンプルコード
コードは、Sheet1、UserForm1、標準モジュールにそれぞれ記載します。
Option Explicit '【定数】 Const TGT_RANGE As String = "C2:C11" '検索欄表示対象のセル範囲
'■シートイベント(Sheet1) '+++ Changeイベント +++ 'セルが変更された場合に発生するイベント Private Sub Worksheet_Change(ByVal Target As Range) '変更したセルが検索欄表示対象セル範囲外の場合は抜ける If Intersect(Range(TGT_RANGE), Target) Is Nothing Then Exit Sub '変更したセルが複数の場合は抜ける If 1 < Target.Cells.Count Then Exit Sub '変更したセルの値が空の場合は抜ける If Len(Target.Value) = 0 Then Exit Sub '変更したセルのアドレスをグローバル変数に格納 strTarget = Target.Address 'フォームを表示 UserForm1.Show End Sub
Option Explicit '■フォームイベント(UserForm) '+++ Initializeイベント +++ Private Sub UserForm_Initialize() Dim strValue As String Dim sinLeft As Single Dim sinTop As Single With ActiveSheet.Range(strTarget) '変数strTargetから対象セルを指定 strValue = .Value '対象セルの値を取得 sinLeft = .Offset(, 1).Left '対象セルの一つ右のセル水平位置取得 sinTop = .Offset(, 1).Top '対象セルの一つ右のセル垂直位置取得 End With '検索ウィンドウ(フォーム)の表示位置設定 Dim dblX As Double Dim dblY As Double With ActiveWindow dblX = .PointsToScreenPixelsX(0) / 96 * 72 + sinLeft * .Zoom / 100 dblY = .PointsToScreenPixelsY(0) / 96 * 72 + sinTop * .Zoom / 100 End With With Me .StartUpPosition = 0 .Left = dblX .Top = dblY - 28 '-28:フォーム垂直位置調整(見出しの高さ分) End With '「商品データ」シートから商品コードと商品名を取得し変数に格納 With Sheet2 Dim varList As Variant Dim lngLastRow As Long lngLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row If lngLastRow = 2 Then lngLastRow = 3 varList = .Range("A2:B" & lngLastRow).Value End With '対象セルの値が商品名に含まれていたらComboBox1のリストに追加する Dim i As Long Dim c As Long With ComboBox1 For i = 1 To UBound(varList) If 0 < InStr(1, varList(i, 2), strValue, vbTextCompare) Then .AddItem varList(i, 2), c 'リスト1列目に商品名を追加 .List(c, 1) = varList(i, 1) 'リスト2列目に商品コードを追加 c = c + 1 End If Next End With End Sub
'■コンボボックスイベント(ComboBox1) '+++ Changeイベント +++ 'コンボボックスに変更があった場合に発生 Private Sub ComboBox1_Change() With ComboBox1 '商品を選択した場合、対象セルの一つ左のセルに商品コードを入力 Range(strTarget).Offset(, -1).Value = .List(.ListIndex, 1) End With End Sub
'■コマンドボタンイベント(CommandButton1) '+++ Clickイベント +++ Private Sub CommandButton1_Click() Unload Me End Sub
Option Explicit '+++ 宣言セクション +++ 'グローバル変数 Public strTarget As String
簡単な解説
■シートイベント
Sheet1のイベントの目的は、検索欄で値を変更したセルのアドレスを取得し、フォームを表示することです。正確なセルアドレスを取得するために、セル範囲の確認、セル個数の確認、入力値の確認を行っています。
コード内のRange(TGT_RANGE)は、検索欄であるセル範囲[C2:C11]を表し、フォームの表示対象セルです。
If Intersect(Range(TGT_RANGE), Target) Is Nothing Then Exit Sub は、
Range(TGT_RANGE)と変更されたセル(Target)の共通セルを確認しています。
共通セルがなければ、変更されたセルは[C2:C11]の範囲外なので、イベントを抜けるようにしています。
■フォームの表示位置
フォームは、Sheet1のセル範囲[C2:C11]に変更があった場合に、アクティブセルの一つ右のセルに表示されます。
フォーム表示位置を設定する詳細はこちらをご覧ください。
フォームの表示対象セル範囲を変更する場合は、Sheet1モジュールの赤文字箇所を変更します。
Const TGT_RANGE As String = "C2:C11"
■リストの作成
フォームのInitializeイベントでComboBoxのリスト作成しています。
Sheet2(「商品データ」シート)のA列の最終行を取得し、A列・B列(商品コード・商品名)の値を変数varListに格納しています。
変数varListに、セルの入力値が含まれているかどうかの判定は、次のコードで行っています。
If 0 < InStr(1, varList(i, 2), strValue, vbTextCompare) Then※
※vbTextCompareは大文字・小文字や全角・半角を区別しません
区別させる場合は vbBinaryCompare を指定します
リストは、AddItemメソッドで追加し、1列目には商品名、2列目には商品コードを設定しています。(リスト内では、1列目は「0」、2列目は「1」のように、0から始まる番号で管理されています。行も同様になります。)
複数列表示する設定にしていないため、リストには1列目の商品名のみ表示されます。
■リストの選択
コンボボックスのChangeイベントは、コンボボックスに変更があった場合に発生します。
コンボボックスに変更があった場合、選択したリストの2列目(商品コード)の値を、対象セルの一つ左のセルに入力します。
書籍紹介140以上のサンプルファイル付き!
知りたいがすぐわかる! やりたいがすぐできる!
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」(Kindle版)
ユーザーフォームを扱えると、VBAでできることが大きく広がります!
本書では、知りたいこと、やりたいことから、逆引きで学びを深められます。
■ 購入:amazon