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関連

    PHPWordを使ってPHPからWordファイルを出力してみる。

    最近オトカドールやルミティアジュエルやらの記事ばかり書いていますが、今…

  2. Office関連

    Office 2019 Commercial Preview版のインストール方法

    「Microsoft、「Office 2019 Commercial …

  3. Office関連

    Office 2013 オンラインヘルプのリンクを集めてみました。

    新機能を把握するためにはヘルプを見るのが一番早い、というわけでOffi…

  4. Office関連

    Office文書をパスワード付きPDFに変換するVBAマクロ

    4年ほど前に書いた、下記記事のマクロがWordでも使えるか?との質問を…

  5. Office関連

    Outlook REST APIに会議室情報を取得するAPIが追加されました。

    松崎さんのツイートで、Outlook REST APIのベータエンドポ…

  6. Office関連

    [リボン・カスタマイズ]グループの表示・非表示をトグルボタンで切り替える。

    数年前に書いた記事に下記コメントをいただきました。Excelに…

コメント

  • コメント (0)

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

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

Time limit is exhausted. Please reload CAPTCHA.

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

Translate

最近の記事

アーカイブ

PAGE TOP