🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

2回答

14813閲覧

VBAのリストボックスであいまい検索入力

asian-ayam

総合スコア8

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2019/12/18 03:32

編集2019/12/18 04:48

お世話になっております。検索ボックスを作成することになり、下記のサイトを参考にコードを書いています。
https://ukkari-ukachan.com/page-67
イメージしているものとしては下記の図のような仕様にしたいと考えています。

![イメージ説明]

リストボックスにはあらかじめ設定したワークシートの中のリストの値を反映させることは出来たのですが、

(1)あいまい検索のテキストボックスを入力して(この場合、「田」と検索したら中田、田中というあいまい検索の候補が出てくるはずがリストボックスが動作せず、候補が出てこない)

(2)試しに(1)の状態のテキストボックスに入力して(例え動作しなくとも)リストボックスの値を選択してもテキストボックスに値が反映されません。

特にエラー表示は出ていないのですが、備えたい機能が機能していない状態です。
VBAのLBound等の動的配列が関連しているかと思うのですが、VBA初心者で且つこの数日間の間にマクロファイルを用意しなければいけないの焦りを感じております。

もしも、このコードが動作しない原因やよりシンプルなリストボックスのあいまい検索のコードがありましたらご教示のほどをお願い致します。

vba

1Private Sub txtSchBox_Change() 2 3 Dim arr() As String 4 Dim sHit As String 5 Dim sNot As String 6 Dim search As String 7 Dim all As Variant 8 Dim i As Long 9 10 ReDim arr(0) 11 i = 0 12 Do 13 arr(UBound(arr)) = Me.LstCandidate.List(i) 14 i = i + 1 15 If i = Me.LstCandidate.ListCount Then Exit Do 16 ReDim Preserve arr(UBound(arr) + 1) 17 Loop 18 19 20 Me.LstCandidate.Clear 21 22 search = Me.txtSchBox.Value 23 24 For i = LBound(arr) To UBound(arr) 25 If arr(i) Like "*" & search & "*" Then 26 sHit = sHit & arr(i) & "," 27 Else 28 sNot = sNot & arr(i) & "," 29 End If 30 Next 31 32 all = sHit & sNot 33 'using delimiter and change into array 34 all = Split(all, ",") 35 36 For i = LBound(all) To UBound(all) 37 If Not all(i) Like "" Then 38 Me.LstCandidate.AddItem all(i) 39 End If 40 Next 41 42End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

なんか無駄に大変な処理をしているようにしか思えないです。
基本的にはテキストボックス変更のタイミングで、

  1. リストボックスをクリア
  2. リストの基になるデータから部分一致するデータをリストに登録

これだけでいいはずです。
以下はInitialize時に見えないリストボックス(Visible=False)に基データを作っておいて、そこから入力データに該当するリストを抽出しています。
面倒だったのでリストボックスにしていますが、ワークシートを参照するのでも考え方に違いはありません。

VBA

1Private Sub TextBox1_Change() 2 ListBox1.Clear 3 ' ListBox2をワークシートの対象範囲に置き換えてもらえればOK 4 For i = 0 To ListBox2.ListCount - 1 5 If InStr(ListBox2.List(i), TextBox1.Text) > 0 Then 6 ListBox1.AddItem ListBox2.List(i) 7 End If 8 Next 9 10End Sub 11 12' テストデータ作成 13Private Sub UserForm_Initialize() 14 ListBox2.AddItem "あいうえを" 15 ListBox2.AddItem "かきくけこ" 16 ListBox2.AddItem "ああいいう" 17 ListBox2.AddItem "いいううえ" 18 ListBox2.AddItem "えおおかか" 19 20 For i = 0 To ListBox2.ListCount - 1 21 ListBox1.AddItem ListBox2.List(i) 22 Next 23End Sub 24

.

投稿2019/12/18 04:54

編集2019/12/18 05:10
ttyp03

総合スコア17000

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asian-ayam

2019/12/19 10:41

ご回答下さり、有難うございます!シンプルな構文で非常に勉強になります!
guest

0

ベストアンサー

リストボックスにはあらかじめ設定したワークシートの中のリストの値を反映させることは出来たのですが、

これはどのタイミングでしてますか。UserForm_Initialize ですか。

呈示のコードは、テキストボックスに入力した値と部分一致するデータがリストボックスにあったらリストの先頭へ移動するというものですが、事前にリストボックスにリストを設定しておけば、正常に動作しました。(リンク先にもそのような動作という説明があります。)

もし、最初はリストボックスは空欄で、テキストボックスに入力した値と部分一致するものをリストボックスに表示させたいということなら一からコードを書き直す必要があります。

上記のような仕様の場合のコード例
ただし、最初(テキストボックスが空欄)の場合は、全リストを表示することにしました。
(その方が使いやすいだろうということで)

ユーザーフォームのモジュール

vba

1Option Explicit 2Private aryList As Variant 3 4Private Sub LstCandidate_Click() 5 Me.txtSchBox.Value = Me.LstCandidate.Value 6End Sub 7 8Private Sub txtSchBox_Change() 9 Dim search As String 10 search = Me.txtSchBox.Value 11 If search = "" Then '空欄の場合は全リスト表示 12 Me.LstCandidate.List = aryList 13 Exit Sub 14 End If 15 16 Me.LstCandidate.Clear 17 search = "*" & Me.txtSchBox.Value & "*" 18 19 Dim Itm As Variant 20 For Each Itm In aryList 21 If Itm Like search Then 22 Me.LstCandidate.AddItem Itm 23 End If 24 Next 25End Sub 26 27Private Sub UserForm_Initialize() 28 aryList = Worksheets(1).Range("A1:A10").Value 'シートのリスト 29 Me.LstCandidate.List = aryList 30End Sub

投稿2019/12/18 04:27

編集2019/12/18 05:02
hatena19

総合スコア34073

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asian-ayam

2019/12/19 10:59

ご回答下さり、有難うございます!あいまい検索のコードと該当する候補以外は消えていく仕組みも非常に助かりました!ちなみにこのあいまい検索のワイルドカードの設定はテキストボックスの入力された文字、例えばTanakaと入力したら"naka"の部分だけを拾ってくるので先頭文字が一致するTanakaが出てこず、Nakataが出てくる設定になっているかと思うのですが、現在のあいまい検索+先頭一致の場合で候補が出てくるようにしたいのですが、どのようなコードを書けばよろしいでしょうか?いくつかIf構文とAndで条件を繋げてみたのですが、上手くいかずに詰まってしまっております。。。
MrIgat

2019/12/20 13:16

先頭一文字だけでよいのであればこれでいかがですか。 If Itm Like search Or Left(UCase(Me.txtSchBox.Value), 1) = Left(UCase(CStr(Itm)), 1) Then
hatena19

2019/12/20 13:24

> 例えばTanakaと入力したら"naka"の部分だけを拾ってくるので先頭文字が一致するTanakaが出てこず、Nakataが出てくる設定になっているかと思うのですが そんなことはないです。部分一致ですので、先頭一致でもでてきます。
MrIgat

2019/12/20 13:49

おそらく、大文字小文字の区別をせずに検索したいという意味のような気がするので、hatena19さんのコードの search = "*" & UCase(Me.txtSchBox.Value) & "*" と If UCase(Itm) Like search Then の2行を変更するとよい気がする。
hatena19

2019/12/21 00:14

> おそらく、大文字小文字の区別をせずに検索したいという意味のような気がするので、 質問文やコメントだけからはそう読み取るのは難しいですが、そうだとすると、 モジュールの先頭に、 Option Compare Text と宣言するのもひとつの手ですね。ただ、こうするとひらがなとカタカナも区別しなくなりますが。
asian-ayam

2019/12/24 02:05

返信が遅くなりました!部分一致のワイルドカードということで認識は合っていたのですね!質問例では日本人の名前を検索というように記載してしまいましたが、実際、作りたいものは外国人の名前が入っているリストなのでアルファベットの大文字と小文字の組み合わせで出来ています(本来はこの検索したい文字の種類にも注意すべきでした)hatena19さんのおっしゃるようにOption Compare Textと宣言したところ、例えばnakaと入力すると候補としてTanakaとNakataが出てくるようになりました!ここ数日間、格闘していたのでイメージ通りになり、喜びは一入です!皆様、ご回答下さり有難うございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問