[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『ユーザーフォームで複数の検索結果を表示したい』(とん)
EXCEL2003です。お力を貸してください。
A行 B行
10 山田孝
15 佐藤義和
120 山田健一
・ ・
・ ・
上記の様にA行に番号、B行に氏名が入力されており(約300件)
ユーザーフォームのTEXTBOX1に山田と入力すると、
10 山田孝 120 山田健一
という様に、山田を含む検索結果を違うBOXで、番号と氏名を
表示させるにはどうしたらいいでしょう?
そして可能であれば、検索結果の120をクリックすると、エクセルのSHEET1の
セルD1にクリックした120が入るようにしたいです。
どなたかよろしくお願いしますm(__)m
ユーザーフォームにTextBox1とListBox1を配置。 ListBox1のColumnCountはプロパティ設定で 2 にしておいてね。 TextBox1に山田といったものを入力してEnterまたはTabをおすと(ほかのコントロールをクリックしてもいい) 対象のものを表示。それを選ぶとD1に転記。
Private Sub ListBox1_Click() Sheets("Sheet1").Range("D1").Value = ListBox1.Value End Sub
Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) Dim v() As Variant Dim c As Range Dim k As Long
ListBox1.Clear With Sheets("Sheet1") With .Range("A1", .Range("A" & .Rows.Count).End(xlUp)) ReDim v(1 To 2, 1 To .Rows.Count) For Each c In .Cells If c.Offset(, 1).Value Like TextBox1.Value & "*" Then k = k + 1 v(1, k) = c.Value v(2, k) = c.Offset(, 1).Value End If Next If k = 0 Then MsgBox "指定の値は存在しません" Else ReDim Preserve v(1 To 2, 1 To k) ListBox1.List = WorksheetFunction.Transpose(v) End If End With End With End Sub
(ぶらっと)
●ただ検索結果が一人の場合、
TEXTBOX1に佐藤を入力すると
15
佐藤義和
と2行になります。これでもOKですが、1行で表示できますでしょうか?
●TEXTBOX1に山田を入力すると
10 山田孝
120 山田健一
と空白がたくさんあるのですが、空白を少なくする事は可能でしょうか?
●ぶらっとさんのコードを貼り付けて使用したら、結果は完璧だったのですが
なぜこのコードで出来るのか、今度の勉強のために理解したいです。
初心者でお手数をお掛けして申し訳ございませんが、各コードの意味を
教えて頂けるととても嬉しいです。
>ただ検索結果が一人の場合、 ・・・2行になります
確かに! ということなら、別の記述方法、AddItem を使ったほうがよかったかもしれないけど 現行のList直接指定のコードを継続して、
変数規定で Dim w() As Variant を追加したうえで
If k = 0 Then MsgBox "指定の値は存在しません" Else ReDim Preserve v(1 To 2, 1 To k) If UBound(v, 2) > 1 Then ListBox1.List = WorksheetFunction.Transpose(v) Else ReDim w(1 To 1, 1 To 2) w(1, 1) = v(1, 1) w(1, 2) = v(2, 1) ListBox1.List = w End If End If
>空白がたくさんあるのですが、空白を少なくする事は可能でしょうか
うん、できる。ListBox1のColumnWidths で、各列ごとの列幅をポイント数で指定可能。 たとえば 20;100 。 ここで、20 という指定もできる。1列目だけを20ポイント、あとはデフォルト値。 今回の場合、後者でいいね。20 は実際に表示してみて加減調整してね。
追記) コードを説明するなら、無理やり対応したアップ済みのコードではなく以下のほうがわかりやすいと思うので TextBox1_BeforeUpdate を以下で置き換えよう。 説明は、それをベースに後程。
Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean) Dim c As Range
ListBox1.Clear With Sheets("Sheet1") With .Range("A1", .Range("A" & .Rows.Count).End(xlUp)) ReDim v(1 To 2, 1 To .Rows.Count) For Each c In .Cells If c.Offset(, 1).Value Like TextBox1.Value & "*" Then ListBox1.AddItem c.Value ListBox1.List(ListBox1.ListCount - 1, 1) = c.Offset(, 1).Value End If Next If ListBox1.ListCount = 0 Then MsgBox "指定の値は存在しません" End If End With End With
End Sub
(ぶらっと)
1行表示も出来ました。そしてColumnWidthsを20ptにすると願い通りの表示です。
後ひとつだけ質問させてくださいm(__)m
現在項目は2つリストに表示させていますが、もうひとつ追加して3つの項目を
リストに表示させるには、どこのコードを変更したらできますか?
番号 氏名 所属
ユーザーフォーム、使いこなせれたらとても便利ですね!頑張って勉強します(とん)
>もうひとつ追加して3つの項目をリストに表示させるには、どこのコードを変更したらできますか
それでは、あとでアップしたコードをベースに。(アップ後、1行、Redim コードを削除してある)
まず、プロパティのColumnCount を 3 にしておく。
で、ListBox1.List(ListBox1.ListCount - 1, 1) = c.Offset(, 1).Value の下に ListBox1.List(ListBox1.ListCount - 1, 2) = c.Offset(, 2).Value を追加。
もし、最初にアップしたコードの処理方法がお好みならそれに対応する変更をアップしてもいいけど?
いずれにしても、コードの説明は後程。
(ぶらっと)
まず、リストボックスやコンボボックスのリストの正体は【配列】 今回の場合は、●行2列の配列ということ。 で、この配列の要素は 0 から始まっている。 配列(2,1) これは、【3行目】の【2列目】を指す。ちょっと、ややこしいね。
で、この配列の行数は ListCountプロパティで取得できる。これは、 1 からカウント。 10 なら この行数は 10行 ということ。
もう1つ、リストで選択されたものがリスト内の何行目だったのかを ListIndexプロパティで 取得できる。これは、 0 から始まっている。 3 なら 【4行目】が選択されたということ。 選択されていない状態では、ListIndex は -1 になっている。
Private Sub ListBox1_Click()
リストで選んだ瞬間にこのルーティンにとんでくる。 この時、Valueプロパティには、選んだ行の、代表の列の値が入っている。 代表の列は ListBox1のBoundColumnで指定。省略時(初期値)は最初の列。 なので、以下のコードで、Sheet1のD1に選んだ行の最初の列の値が転記されることになるね。
Sheets("Sheet1").Range("D1").Value = ListBox1.Value
Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
BeforUpdateには、TextBox1にデータを【入れ終わった時】にとんでくる。 よく、テキストボックスのChangeイベントを使う人がいるけど、Changeイベントは テキストボックスに1文字入力するたびに、発生するので、特殊な用途以外は 使わないほうがいい。
ListBox1.Clear
まず、前回抽出されていたリスト内容をクリア
With Sheets("Sheet1") With .Range("A1", .Range("A" & .Rows.Count).End(xlUp)) For Each c In .Cells
これはシートの指定列からデータが存在するだけセルを1つずつ取り出す定番コード
If c.Offset(, 1).Value Like TextBox1.Value & "*" Then
取り出したA列のセルの1つ右、つまり B列の値を TestBox1に入力した値に "*" をつけたもので【Like】判定。 Like についてはヘルプ等で調べてみてね。
ListBox1.AddItem c.Value
ListBox1 に行を追加し、その行の1列目に指定の値をいれる。
ListBox1.List(ListBox1.ListCount - 1, 1) = c.Offset(, 1).Value
追加した行の2列目に値をセット。 追加した行は、追加の結果の、このリストの行数が追加した行番号ということになるけど コメントしたようにリストの行番号、列番号は 0 からはじまるので、ListCount - 1 を行番号にしている。 列は2列目なので 1 。
(ぶらっと)
LIKE演算子も調べてみました。
それによくCHAGEイベント使っていました(笑)
BeforeUpdateの方がいいですね!
ぶらっとさんの回答をじっくり勉強し、今後自分で応用が利かせるようにしていきます!
ぶらっとさん そしてこのサイトに感謝です。
ありがとうございましたm(__)m
(とん)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.