エクセルVBAでFindを使った検索について

このQ&Aのポイント
  • エクセルVBAのFindメソッドを使った検索について質問です。
  • エクセル2003でVBAを勉強し始めた方が検索機能の実装について教えてほしいです。
  • また、一度他のコードを実行した後に検索を行うと検索結果が表示されなくなる問題についても解決したいです。
回答を見る
  • ベストアンサー

エクセルVBAでFindを使った検索について

エクセル2003でVBAを勉強し始めたものです。 findを用いた検索についてご教授をお願いしたく、ご質問させていただきます。 まず、 <シート1> A列:受付No. B列:氏名 C列:物件名 <シート2> A~F列:省略 G~O列:物件名 とあります。 シート1上にコマンドボタンがあり、クリックするとシート1への入力用フォームが開きます。 さらに、そのフォーム内のテキストボックスに物件名を入力するのですが、テキストボックス内でダブルクリックで、物件検索用のフォームが開きます。 物件検索用フォーム内のテキストボックス(Text物件名検索)に文字列を入力し、コマンドボタン(command物件名検索)をクリックすると、フォーム内下部のリストボックス(List物件検索結果)内に、シート2のG~O列を検索した結果が並ぶようになっています。 その候補の中から選択したものが、シート1の物件名の列に並ぶようにしたいのです。 そこで、エクセルファイルを開いたすぐ後は、検索結果が意図通りに表示するのですが、一度他のコード(マクロにてシート1の行削除等)を実行した後、再度物件検索を行うと、検索結果が“なし”(その場合は「見つかりませんでした」とメッセージボックスが開くようにしてあります)となってしまいます。 変数の扱いがわるいのでしょうか?・・・ どうぞご教授のほどよろしくお願いいたします。 以下、検索用フォームのテキストボックス入力後、コマンドボタン(command物件名検索)をクリックしたときの処理コードです。 --------------------------------------- Private Sub command物件名検索_click() Dim bname As String Dim fndrange As Range Dim firstcell As String bname = Text物件名検索.Text Set fndrange = Sheets("TBオーナー").Columns("g:o").Find(bname) If bname = "" Then MsgBox ("キーワードを入力してください") Exit Sub Else If fndrange Is Nothing Then MsgBox ("見つかりませんでした") Text物件名検索.Text = "" Text物件名検索.SetFocus Else If Not fndrange Is Nothing Then firstcell = fndrange.Address Do Set fndrange = Sheets("TBオーナー").Columns("g:o").FindNext(fndrange) List物件検索結果.AddItem fndrange.Value Loop While Not fndrange Is Nothing And fndrange.Address <> firstcell End If End If End If End Sub ----------------------------------------- また、関係あるかわかりませんが、他のコード(シート1から行を削除するマクロ)も掲載させていただきます。 以下、 -------------------------------------- Private Sub Command削除_Click() Dim t As Long Dim DelNo As String Dim delNos As Long Dim s As Range DelNo = InputBox("削除するデータNOを入力してください") delNos = Val(DelNo) Set s = Sheets("TBマスター").Columns("A").Find(delNos, lookat:=xlWhole) If DelNo = "" Then Exit Sub ElseIf s Is Nothing Then MsgBox ("データがありません") Exit Sub Else t = Sheets("TBマスター").Columns("A").Find(delNos, lookat:=xlWhole).Row Rows(t).Delete End If End Sub --------------------------------------------------------- 質問のが悪いかも知れませんが、必要なことがあれば随時追記させてください。 以上、よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Musaffah
  • ベストアンサー率36% (37/101)
回答No.3

再度#2です。 質問者様のコードを基に適当に環境作って動かしてみたんですが、Nothingになることはありませんね。 「行削除によって本当に検索文字列がなくなった」というオチはありませんか? また、2回連続して(いったん物件検索フォームを閉じて再度表示させて)「command物件名検索_click()」を実行するとどうなります?

truemind2010
質問者

お礼

解決いたしました!! 原因は、行削除時のコード内の、『findメソッド』の引数“lookat:=xlwhole”が、次に物件名検索するときのfindの引数として維持されていたようです。物件検索時のfindは部分一致で行いたかったのです。が、その旨、説明をしおておけば、回答者様へもわかりやすく質問ができたものと、反省しております。この度は本当にありがとうございました。また、日々勉強していきたいと思います。

truemind2010
質問者

補足

ご返答いただきありがとうございます。 >「行削除によって本当に検索文字列がなくなった」というオチはありませんか? 削除に関する説明が不足していたようで、申し訳ございません。補足させていただきます。 まず、シート1には A列   B列 NO   物件名 1    物件○○ 2    物件□□ 3    物件△△      ・      ・       ・ こんな感じで並んでいます。 処理の流れとしては、 シート1上のcommand削除クリック ↓ インプットボックス表示 ↓ インプットボックスに入力されたNOを、シート1のA列から検索 ↓ 検索された値を含む行番号を取得 ↓ その行全体を削除 という感じです “削除”するのは、シート1の縦方向に並んだデータの1行のことです。検索されるデータのあるシート2については削除される部分はないので、検索文字列がなくなったということはないです。 >また、2回連続して(いったん物件検索フォームを閉じて再度表示させて)「command物件名検索_click()」を実行するとどうなります? 問題なく動作いたします。 また、削除を実行すると、その後検索できなくなるとご説明しましたが、削除実行しなくとも、つまり、削除時にNOを指定するための、インプットボックスを表示し、キャンセルをするだけでも、その後検索ができなくなることが判明しました。 とにかく、もういちど初めから作り直してみようと思います。いろいろと教えていただき本当に感謝しています。

その他の回答 (2)

  • Musaffah
  • ベストアンサー率36% (37/101)
回答No.2

[F9](ブレークポイント)と[F8](ステップ実行)を用いて、ご自分でデバッグことをお勧めします。 例えば、 bname = Text物件名検索.Text の行にブレークポイントを設定した後に、普通に操作して下さい。 ブレークポイントを設定した行で一時中断となります。 そこで([F8]を押しながら)1行ずつプログラムを実行していくと、具体的にどこがおかしいかが明確になると思います。 その上でどうしても「何故このような動き(値)になるかわからない」となった場合に質問されると、より具体的に質問できます。(=皆も回答しやすい質問になると思います。) 的を得た答えにはなっていないと思いますが、デバッグもプログラミングをしていく上で必要な技術です。 これもVBAの勉強だと思ってチャレンジしてみて下さい。

truemind2010
質問者

補足

ご回答ありがとうございます。 早速教えていただいたデバッグについて、行ってみました。 結果、 Set fndrange = Sheets("TBオーナー").Columns("g:o").Find(bname) のところで、bnameには文字列が入っているのですが、fndrangeの値が、“nothing”となってししまうことが、問題とわかりました。1回目の検索時はしっかりと検索結果が入るのですが・・・

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.1

>シート1への入力用フォームが開きます。 このフォームとはユーザーフォームのことか。 シートの中のセル範囲をフォーム(入力書式を持った様式)と見立てたのか。 >Sheet1のA列:受付No. B列:氏名 C列:物件名 のことか? VBAでフォームというと(ユーザー)フォームのことを言うことが多いので注意。 >シート1への入力用フォームが開きます。 というのも違和感がある。シート1が選択された常態になるということか >シート1への入力用フォームが開きます。 これも、フォームとはユーザーフォームのことか。シートのセル範囲のことか? ーーー もう少し質問の課題を絞って質問できませんか。 質問者がやろうとしている、シートやフォームの構成がよくわからない。 ーー コードを載せる前に、下記仕組みなどを明確に質問すること(むしろこの設計を質問して洗練させるべきと思うが) 検索条件(検索語)を入力する場所(シート?フォーム?) 検索実行のトリがーーコマンドボタン(第1段のトリガ)らしい 検索するデータのあるシートは何処(シート・列)? 検索が2段構え、らしいが (検索語入力ー検索ーリストボックス表示ー選択ー検索ー結果をシート? こういう構成をはっきりと質問に書くべき。 第2段のトリがはコマンドボタンらしい=>ListBoxの選択クリックで良いのでは。 結果はシート?どこのシート? など ーー コードも丸投げコピーしただけで、質問者の検討がなされておらず、回答者の負担が大きいのでは。

truemind2010
質問者

お礼

VBAをはじめたばかり&はじめての投稿で、至らないことばかりでしたが、いろいろと教えてくださって本当にありがとうございました。今後のためにも非常に勉強になりました。

truemind2010
質問者

補足

ご回答ありがとうございます。質問の仕方について、配慮がかけていたようですみません。その辺ご教授いただき、今後の勉強になります。 さて、 全体の流れとしましては、 シート1への入力用ユーザーフォームをシート1上に設置したコマンドボタンにて開く ↓ 入力用ユーザーフォーム内のテキストボックスをダブルクリックし、物件検索用ユーザーフォームを開く ↓ 物件検索用ユーザーフォーム内のテキストボックス(Text物件名検索)に検索語を入力し、コマンドボタン(command物件名検索)クリック ↓ 検索するデータのあるシート2のG列~O列から検索 ↓ 物件検索用ユーザーフォーム内のリストボックス(List物件検索結果)に、検索結果が表示される ↓ リストボックス内のアイテム選択し、入力用ユーザーフォーム内テキストボックスに入力 ↓ 入力用ユーザーフォーム内、登録ボタン(コマンドボタン)クリックで、シート1の物件名(C列)に入力。 以上、こんな流れです。※“フォーム”とは全てユーザーフォームのことです。明確にしておくべきでした。 設計についてまず勉強が必要ですね・・・おっしゃるとおり(^-^) もっと回答者への配慮がなされ、うまく質問ができるように頑張ります!

関連するQ&A

  • VBAを使って検索をしたい

    VBAを使って検索をしたい EXCEL2007を使っております。 フォームを立ち上げて日付を入れるとシートの検索を行い、リスト内にその日付のA~Gまでのセルの内容が表示され、それらを別シートに貼り付けるといったことをしたいのですが、複数のセルの情報をリスト内に表示をするのが、よくわからず教えていただきたく思います。 フォーム内のテキストボックスに検索する日付を入れると 画像でいうところのA列を検索し、その日付内のA~Gをリストに表示して、ボタンを押すと貼り付けるといった、動きにしたいのですが、お願いします。 現状検索BOXに以下の記述をしてます これでは、A列のものだけが出てきます。お助けください。 ************************* Private Sub TextBox1_Change() Dim r As Range, FirstCell As Range, rng As Range Dim vnt As Variant Dim prow As Long Dim s As Worksheet Dim cnt As Long Set s = Sheets("sheet2") Set rng = Intersect(s.Range("a:a"), s.UsedRange) '検索キー Set r = rng.Find(What:=TextBox1.Text) If r Is Nothing Then MsgBox "見つかりませんよ" GoTo Exit_sub End If Set FirstCell = r ReDim vnt(0) vnt(0) = s.Cells(r.Row, 1).Resize(1, 5).Value '検索位置 prow = r.Row cnt = 1 Do Set r = rng.FindNext(r) If Not r Is Nothing And (r.Address <> FirstCell.Address) _ And (FirstCell.Row <> r.Row) And (prow <> r.Row) Then ReDim Preserve vnt(UBound(vnt) + 1) vnt(UBound(vnt)) = s.Cells(r.Row, 1).Resize(1, 5).Value '検索位置 prow = r.Row cnt = cnt + 1 End If Loop While r.Address <> FirstCell.Address ' If cnt = 1 Then vnt = s.Cells(FirstCell.Row, 1).Resize(1, 5).Value '検索位置 If cnt > 1 Then vnt = Application.Transpose(Application.Transpose(vnt)) ListBox1.List = vnt ' Set FirstCell = Nothing Erase vnt Exit_sub: If cnt = 0 Then ListBox1.Clear Set r = Nothing Set rng = Nothing Set s = Nothing End Sub

  • エクセルVBA初心者です。

    エクセルVBA初心者です。 「テキストボックスとコマンドボタンを使って、シートのA列にあるセルの文字列を左から検索する」という事をやりたいのですが、うまくいきません。お教えください。ちなみにCtrl+Fではなく、VBAで。 Private Sub TextBox1_Change() Dim R As Range With ActiveWorkbook.Worksheets("Sheet名") Set R = .Columns(3).Find(Me.TextBox1.Value) End With If R Is Nothing Then MsgBox "該当セルなし" Else R.Activate End If Set R = Nothing End Sub としましたが、テキストボックス入力+Enterで出来てしまい、コマンドボタンが機能しません。また、BackSpaceやDelをすると、他のセルに飛んでしまいます。????

  • エクセルVBA シート名の部分一致検索について エクセル2007

    VBAでエクセルの全シート名を部分一致で検索したいと考えています。 そこで以下のコードを書いたのですが、 インプットボックスにどんな文字列を入力しても全てのシート名を 取得してしまって途方にくれています。 どなたかお助けください。 Sub test01() Dim name As String Dim ws As Worksheet shn = InputBox("検索文字列を入力") For Each ws In ThisWorkbook.Worksheets If ws.Name Like " * " & name & " * " Then ws.Activate MsgBox ws.Name End If Next ws End Sub

  • Excel VBA テキストボックスを検索

    テキストボックス3に数値を入力し ExcelのA列にあるか検索をかける。 ある場合は、B列の同じ行に 「みーつけた!」と入力。 その設定で組んでみたのですが、 テキストボックス3にデータを6桁入力しようとすると 6桁目にオーバーフローエラーが出ます。 このプログラムの何処がおかしいのでしょうか? Private Sub TextBox3_Change() Dim Number As Integer If TextBox3.Value <> "" Then '空じゃない場合 Number = TextBox3.Value Call 検索(Number) MsgBox TextBox3.Value End If End Sub Sub 検索(ByVal Number As Variant) Dim FoundCell As Range Set FoundCell = Range("A:A").Cells.Find(What:=Number, lookat:=xlPart) If FoundCell Is Nothing Then Else FoundCell.Activate Range("O" & ActiveCell.Row).Value = "みーつけた!" End If End Sub

  • エクセルVBAであいまい検索フォームを作りたいです。

    エクセルVBAであいまい検索フォームを作りたいです。 (Ctrl+Fではなく) 商品群A・商品群B・商品群C・・・・と分けられたシートの すべてのA列に、商品名が入っています。 テキストボックスと【検索】ボタンと【次を検索】ボタンのみの 単純な検索用ユーザーフォームから 商品名をシートをまたいで検索し、 Ctrl+Fと同じように該当セルに移動、 次を検索で次の商品へ移動、 すべてのシートに該当商品が無ければ メッセージボックス「該当する商品はありません」 なんとなく出来そうな気がしてチャレンジしましたが、 基本がなっていないため行き詰りました。 (自動マクロを少しいじる程度なので・・・) とんでもなく支離滅裂ですが、チャレンジしたゴミコードを晒します。 順番がおかしいのは判るのですが、どうすればいいのか。。。 どなたか、このコードを正し添削して頂けませんか。 (あ、このコードにこだわっているわけではないので、 もっと他に適した方法があるのなら、それを教えてください) よろしくお願い致します。 ちなみに、作成はexcel2007ですが、2000・2003に配布します。 Dim s As Variant Dim c As Range Dim f As Range For Each s In Worksheets 'ブック内各シートに繰り返し With s s.Select 'シートを選択 Set f = Columns("B").Cells 'B列を変数にセット Set c = f.Find(What:=Trim(strData), LookIn:=xlValues, MatchByte:=False, LookAt:=xlPart) 'FINDでstrData(userformからの入力した文字列)をあいまい検索としてセット If Not c Is Nothing Then Application.Goto c, True '見つかった時は該当セルに飛ぶ Else End If End With Next End Sub

  • 部分一致での検索方法

    Access2000のVBAで3つのオプションボタンでフィールドを選択し、1つのテキストボックス(オプションテキスト)に文字列を入力して検索ボタンで検索するプログラムを以下のような記述の仕方で作成しました。 完全一致した場合は問題なく表示されるのですが、できればテキストボックスに入力した文字列が部分一致した場合でも表示させるようにしたいのですが、どうすればよいかがわからないので教えてください。 Private Sub オプション検索_Click() Dim stFilter As String Dim stDocName As String If 特定検索 = 1 Then stDocName = "フォーム名"   stFilter = "フィールド名1='" & テキストボックス名 & "'" DoCmd.OpenForm stDocName, , , ElseIf 特定検索 = 2 Then stDocName = "フォーム名" stFilter = "フィールド名2='" & テキストボックス名 & "'" DoCmd.OpenForm stDocName, , , stFilter ElseIf 特定検索 = 3 Then stDocName = "IPForm" stFilter = "フィールド名3='" & テキストボックス名 & "'" DoCmd.OpenForm stDocName, , , stFilterOn End If End Sub

  • ユーザーフォームでの任意の文字を含む検索について

    初心者の質問で申し訳ございません。 ユーザーフォームを利用して検索ボタンを作りました。 ユーザーフォームでテキストボックスを2個と コマンドボタン1個を作成し、 テキストボックス1に検索したい氏名を入力して コマンドボタンを押すと、 ワークシートに作成されたデータのD列から 一致するものを検索し、 一致したデータのA列にある「番号」をテキストボックス2、 表示する。 このサイトで教えていただき、以下のようなプログラムで 検索することができました。 しかし、テキストボックス1の文字が完全に一致すれば結果は出るのですが、 文字を含むものを検索するように改良したいのですがどのようにすればいいのか 分からず困っています。 よろしくお願いいたします。 ************************** Private Sub CommandButton1_Click() Dim res  If TextBox1.Text <> "" Then   res = Application.Match(TextBox1.Text, Sheets("データ").Columns(4), 0)   If IsNumeric(res) Then    TextBox2.Text = Sheets("データ").Cells(res, "A").Value   Else    TextBox2.Text = "Not Found"   End If  Else   TextBox2.Text = ""  End If End Sub

  • エクセルVBA 別シートからのコンボボックス連動

    エクセルVBA 別シートからのコンボボックス連動について Book1(多人数入力用ブック) ・入力シート ・データ用シート Book2(反映用ブック) ・シート1 Book1にコンボボックスが2列 テキストボックスが2列 * 6行のユーザーフォームを作成しました。 コンボボックス1 コンボボックス2 テキストボックス1 テキストボックス2 コンボボックス3 コンボボックス4 テキストボックス3 テキストボックス4 ・ ・ ・ 左のコンボボックスで「あ」が選ばれたときには、右のコンボボックスで「あ行の顧客」・・・というように連動させたいと考えております。 データ用シートのデータは、   A      B          C 1 あ あ行で始まる顧客 か行で始まる顧客 2 か 3 さ 4 た 5 な 6 Private Sub UserForm_Initialize() Dim c As Range ComboBox1.RowSource = "データ用シート!A1:A9" End Sub Private Sub ComboBox1_Change() 'Dim Rng As Range 'Dim i As Long i = ComboBox1.ListIndex If i > -1 Then Dim c As Range Set Sh = Worksheets("データ用シート") Set Rng = Worksheets("データ用シート").Range("B2:I30") ComboBox2.Value = "" ComboBox2.RowSource = Rng.Columns(i + 1).Address End If End Sub 上記コードですと、コンボボックス2が入力シートのデータを表示してしまいうまくいきません。 欲をいえば、 Book1(多人数入力用ブック)入力シートの特定セルに コンボボックス2・テキストボックス1 コンボボックス4・テキストボックス3というように続けて1セルに反映 Book2(反映用ブック)シート1に コンボボックス2・テキストボックス1・テキストボックス2 を各1セル 1行に反映させたいと考えております。 まったく知識がないのですが 仕事上どうしても必要となったので、各種サイトを見よう見真似でやっております。 ご助力いただければ幸いです。

  • エクセルVBAのFINDの質問です。

    エクセルVBAのFINDの質問です。 シート1    A    B    C     D 1 コード1 コード2 コード3 名 称 2  4    1     1 3  4    2     2 4  4    3     1 シート2    A    B 1 コード1 名 称 2  1   名称1 3  2   名称2 やりたいことは、シート1のD列に、シート1のコード3をもとにシート2から名称を取得したいのです。 下記に記したプログラムだと最初のFINDNEXTは動くのですが、 2回目でエラーになってしまい、次を読んでくれません。 どなたか、ご教授頂けますでしょうか。 シート1の検索条件はコード1の"4"です。 シート1のコード1は重複キーで、一レコードずつ読んで行き、各レコード毎にシート2を読みたい のです。 Dim シート1 As Worksheet Dim シート2 As Worksheet Dim obj As Object Dim Lin As Integer Dim mykey As Integer Dim obj1 As Object Dim Lin1 As Integer Dim mykey1 As Integer Dim st_Lin As Integer Set シート1 = ThisWorkbook.Worksheets("シート1") Lin = シート1.Cells(シート1.Rows.Count, 1).End(xlUp).Row mykey = "4" Set obj = シート1.Range("A1", "A" & Lin).Cells.Find(What:=mykey, _ LookIn:=xlValues, _ lookat:=xlWhole, _ SearchOrder:=xlByColumns) If obj Is Nothing Then   MsgBox ("異常です")   Exit Sub Else   st_Lin = obj.Row   Do Until obj.Row <> st_Lin    Set obj = シート1.Range("A1", "A" & Lin).FindNext(obj)    If obj Is Nothing Then     Exit Do    Else     Set シート2 = ThisWorkbook.Worksheets("シート2")       With シート2          Lin1 = .Cells(シート2.Rows.Count, 1).End(xlUp).Row          mykey1 = シート1.Cells(obj.Row, 3).Value          Set obj1 = .Range("A1", "A" & Lin1).Cells.Find          (What:=mykey1,LookIn:=xlValues,lookat:=xlWhole,SearchOrder:=xlByColumns)          If obj1 Is Nothing Then           MsgBox ("名称取得できませんでした")           Exit Sub          Else            シート1.Cells(obj.Row, 4).Value = .Cells(obj1.Row, 2).Value          End If       End With    End If   Loop End If

  • VBA FIND時のIFの使い方について

    VBA素人です。教えてください。 添付シートのようなデータがあるとします。 ユーザーフォームにテキストボックスを作成し、 (1)シート内の型式を型式BOXに手入力で入れる (2)良品数を手入力で入れる (3)日付を手入力で入れる(初期設定はDateをかえす) (1)~(3)を入力し、入力コマンドボタンで型式と日付がFINDするセルに 良品数を入れるコードを下記作成しました。 シート内に対象の型式、日付があれば、うまく作動するのですが、 型式、日付両方が無い場合、もしくはどちらか片方が無い場合は、 うまく作動しません。 おそらく型式FIND~IF、日付FIND~IFの使い方が悪いと思います。 型式がシート内に無ければ、型式エラーとしマクロを抜ける。 型式があり、日付が無ければ、日付エラーでマクロを抜けるコードを教えてください。 なお、型式を手入力で入れていますが、シート内の("B:B")セルを選択すると自動で型式テキストボックスに入れる方法もご教示下さい。 Private Sub UserForm_Initialize() 型式BOX = ""'テキストボックス 良品BOX = ""'テキストボックス 日付BOX = Date'テキストボックス 型式BOX.SetFocus End Sub Private Sub 入力_Click() Application.ScreenUpdating = False Application.EnableEvents = False If Len(型式BOX.Value) = 0 Then MsgBox "型式が未選定です" Cancel = True ElseIf Len(良品BOX.Value) = 0 Then MsgBox "良品が未入力です" Cancel = True ElseIf Len(日付BOX.Value) = 0 Then MsgBox "日付が未入力です" Cancel = True Else Dim a As Variant a = 型式BOX.Value Dim b As Date b = 日付BOX.Value On Error Resume Next Columns("B:B").Select ActiveSheet.Cells.Find(a, , , xlWhole, xlByRows, xlNext, False).Select X = ActiveCell.Row If Err = 91 Then MsgBox (prompt) & a & "の型式はありません", _ (vbOKOnly + vbExclamation), ("型式検索結果") Err.Clear End If On Error Resume Next Rows("1:1").Select ActiveSheet.Cells.Find(b, , , xlWhole, xlByColumns, xlNext, False).Select Y = ActiveCell.Column If Err = 91 Then MsgBox (prompt) & b & "の日付はありません", _ (vbOKOnly + vbExclamation), ("日付検索結果") Err.Clear   End If Cells(X, Y) = 良品BOX.Value End If End Sub

専門家に質問してみよう