トップ > 逆引きで学ぶ ユーザーフォーム&コントロール > 追加章 現場で活かせる!実践ユーザーフォーム > B-01 セルの入力値に応じた候補リストを作成・表示(ComboBox)

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、標準モジュールにそれぞれ記載します。


【Sheet1】
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
【UserForm1】
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

ページトップへ戻る
Copyright(C) 2009- 坂江 保 All Rights Reserved.