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のバージョンによっては上手く動作しないかもしれません…。)

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

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

[PowerPoint]図やスライドをSVGとして保存する機能が追加されました。前のページ

[Excel]XLOOKUP関数でより簡単に値を検索できるようになりました!次のページ

関連記事

  1. Office関連

    64ビット環境かどうかを判別するVBAマクロ

    2年以上前にMicrosoft Community(当時はMicros…

  2. Office アドイン

    Excel向けPower BI カスタム ビジュアル機能の紹介

    Power BI ブログの記事「Excel announces new…

  3. アイコン一覧

    Office 2013 アイコン一覧(C)

    ・Office 2013 アイコン一覧 NUM…

  4. Office関連

    Office クリップボードをマクロで操作する(MSAA)

    MSDNフォーラムに質問がありましたが、Office クリップボードを…

  5. アイコン一覧

    Office 2013 アイコン一覧(U)

    ・Office 2013 アイコン一覧 NUM…

  6. Office関連

    Gmail APIを使ってメール送信するVBAマクロ(3)

    前回、前々回とGmail APIを扱ってきましたが、今回は前々回の記事…

コメント

  • コメント (0)

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

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

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP