Office関連

[VBA]ユーザーフォーム上のコンボボックスでオートコンプリート機能を実装する方法

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

仕組みは下記のように非常に単純です。

  1. ユーザーフォームが開いたとき(UserForm_Initialize)に、対象となるコンボボックスのリストを保存用のコンボボックスにコピーする。
  2. コンボボックスでキーが押されたとき(KeyUpイベント)に、入力された文字列を元にフィルタリングして、保存用のコンボボックスからリストを作成する。

唯一工夫した点は、DropDownメソッドで開いたリストを閉じる処理でしょうか。
下記コードの部分で実装していますが、これがなかなか上手くいきませんでした。

If accCbo.accName(&H2&) = "閉じる" Then
  Set accLst = accCbo.accChild(&H3&)
  accLst.accDoDefaultAction &H0&
  'DoEvents
End If

最初はユーザーフォームにキーコードを送信して無理やり閉じたりしていましたが、最終的には上記の形に落ち着きました。
(もしかしたら、OSやOfficeのバージョンによっては上手く動作しないかもしれません…。)

コンボボックスのオートコンプリート機能、使ってみると項目を選択しやすくなり、中々便利なものでした。

クラス化して使いまわしできるようにすれば、もっと使い勝手が良くなるかもしれませんが、私は普段ユーザーフォーム自体使う機会が少ないので、今回はここまでにしておきます。

関連記事

  1. Office アドイン

    [Office用アプリ]Apps for Office サミット!で登壇しました。

    21日(土)に開催されたOffice 用アプリの勉強会「Apps fo…

  2. Office関連

    古い形式のWordテンプレートを新しい形式に一括変換するVBScript

    古い形式のWordテンプレート(dot)を新しい形式(dotx,dot…

  3. Office関連

    Excel 2016でマップグラフを作成する。

    12月6日、Office Insider向けに、Office 2016…

  4. Office関連

    ConvertToTextメソッドを使ってテーブルを二次元配列に変換するWordマクロ

    WordのTableオブジェクトには、テーブルを解除して文字列に変換す…

  5. アイコン一覧

    Office 365アイコン(imageMso)一覧(Q)

    Office 365のデスクトップ版Officeアプリケーション(Wo…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP