MSDNフォーラムに「ユーザーフォーム上のコンボボックスで、任意の文字列でアイテムをフィルタリングしたい」といった質問がありました。
早い話がオートコンプリート(サジェスト)機能ですね!
コンボボックスにはMatchEntryプロパティも用意されていますが、今回の用途では物足りません。
そこで、KeyUpイベントを利用した代替手段を考えてみることにしました。
KeyUpイベントによるオートコンプリート機能の実装
さっそくコードです。
ちなみに、下記コードはExcelに限らずWordやPowerPointでもそのまま使用することができます。
'※UserFormに記述 Option Explicit Private WithEvents cboAutoComplete As MSForms.ComboBox Private cboStored As Object Private Sub UserForm_Initialize() Dim v As Variant Dim i As Long 'コンボボックスのリスト設定 '下記氏名は http://kazina.com/dummy/ で作成したダミーデータ v = Array("中原 草太", "柳 隆", "相田 功補", "武田 淳", "関根 守", "松井 美佐", "奥 博明", _ "井上 俊二", "山中 なつみ", "村瀬 由樹", "とよた 京子", "富岡 由宇", "泉 まみ", _ "福岡 憲一", "堀 サダヲ", "小柳 拓郎", "梅沢 季衣", "角 鉄洋", "古谷 詩織", _ "石田 雅之", "海老原 美咲", "遠山 郁恵", "西浦 光", "大沼 しぼり", "奈良 佳乃", _ "有村 美幸", "岩間 広司", "西 明日", "古沢 早織", "柴田 りえ", "西村 美幸", _ "三船 麻緒", "大熊 なつみ", "大泉 芽以", "坪井 有海", "今 玲那", "沢井 奈月", _ "伊藤 莉緒", "山中 春樹", "宮迫 裕司", "有田 ヒカル", "有田 あさみ", "田辺 砂羽", _ "日下 美佐子", "外山 陽子", "池田 ちえみ", "松崎 知史", "吉沢 浩太郎", "田原 惇", _ "金児 路子") With ComboBox1 .MatchEntry = fmMatchEntryNone For i = LBound(v) To UBound(v) .AddItem v(i) Next End With '保存用のComboBoxにリストをコピー Set cboAutoComplete = ComboBox1 Set cboStored = CreateObject("Forms.ComboBox.1") cboStored.List = cboAutoComplete.List End Sub Private Sub cboAutoComplete_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Dim accCbo As Office.IAccessible Dim accLst As Office.IAccessible Dim i As Long Set accCbo = cboAutoComplete Select Case KeyCode '動作するキー指定 ※必要に応じて変更 '変換(28),無変換(29) Case 28, 29, vbKeyBack, vbKeySpace, vbKeyDelete, _ vbKeyA To vbKeyZ, vbKey0 To vbKey9, vbKeyNumpad0 To vbKeyNumpad9 'フィルタリングしてアイテム追加 cboAutoComplete.Clear For i = 0 To cboStored.ListCount - 1 If cboStored.List(i) Like "*" & cboAutoComplete.Text & "*" Then cboAutoComplete.AddItem cboStored.List(i) End If Next '開いているドロップダウンを閉じる If accCbo.accName(&H2&) = "閉じる" Then Set accLst = accCbo.accChild(&H3&) accLst.accDoDefaultAction &H0& 'DoEvents End If cboAutoComplete.DropDown End Select End Sub
仕組みは下記のように非常に単純です。
- ユーザーフォームが開いたとき(UserForm_Initialize)に、対象となるコンボボックスのリストを保存用のコンボボックスにコピーする。
- コンボボックスでキーが押されたとき(KeyUpイベント)に、入力された文字列を元にフィルタリングして、保存用のコンボボックスからリストを作成する。
唯一工夫した点は、DropDownメソッドで開いたリストを閉じる処理でしょうか。
下記コードの部分で実装していますが、これがなかなか上手くいきませんでした。
If accCbo.accName(&H2&) = "閉じる" Then Set accLst = accCbo.accChild(&H3&) accLst.accDoDefaultAction &H0& 'DoEvents End If
最初はユーザーフォームにキーコードを送信して無理やり閉じたりしていましたが、最終的には上記の形に落ち着きました。
(もしかしたら、OSやOfficeのバージョンによっては上手く動作しないかもしれません…。)
コンボボックスのオートコンプリート機能、使ってみると項目を選択しやすくなり、中々便利なものでした。
クラス化して使いまわしできるようにすれば、もっと使い勝手が良くなるかもしれませんが、私は普段ユーザーフォーム自体使う機会が少ないので、今回はここまでにしておきます。
この記事へのコメントはありません。