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 アドイン

    [Office用アプリ]TechEd North America 2013のセッション資料

    アメリカ・ニューオリンズで現地時間6月3日から6日にかけて開催された開…

  2. アイコン一覧

    Office 365アイコン(imageMso)一覧を作成するにあたって

    Office 2013のアイコン一覧を公開してから4年ほど経ち、その間…

  3. アイコン一覧

    Office 365アイコン(imageMso)一覧(X,Y,Z)

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

  4. アイコン一覧

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

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

  5. Office関連

    「クラシックスタイルメニュー for Office 2010」のOffice 2013対応状況

    私が下記ページで公開しているフリーソフト「クラシックスタイルメニュー …

コメント

  • コメント (0)

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

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

Time limit is exhausted. Please reload CAPTCHA.

Translate

最近の記事

アーカイブ

PAGE TOP