Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2089 / 13645 ツリー ←次へ | 前へ→

【69938】2つの言葉で検索したい ごん 11/9/26(月) 9:35 質問[未読]
【69939】Re:2つの言葉で検索したい UO3 11/9/26(月) 10:07 回答[未読]
【69948】Re:2つの言葉で検索したい ごん 11/9/27(火) 19:34 お礼[未読]
【69953】Re:2つの言葉で検索したい ごん 11/9/28(水) 9:41 質問[未読]
【69943】Re:2つの言葉で検索したい kanabun 11/9/26(月) 18:44 発言[未読]
【69951】Re:2つの言葉で検索したい ごん 11/9/27(火) 20:39 発言[未読]
【69952】Re:2つの言葉で検索したい UO3 11/9/28(水) 9:18 発言[未読]
【69954】Re:2つの言葉で検索したい ごん 11/9/28(水) 9:48 発言[未読]
【69955】Re:2つの言葉で検索したい UO3 11/9/28(水) 11:48 回答[未読]
【69956】Re:2つの言葉で検索したい UO3 11/9/28(水) 11:55 回答[未読]
【69957】Re:2つの言葉で検索したい ichinose 11/9/28(水) 13:42 発言[未読]
【69958】Re:2つの言葉で検索したい UO3 11/9/28(水) 14:51 発言[未読]
【69959】Re:2つの言葉で検索したい UO3 11/9/28(水) 14:52 発言[未読]
【69989】Re:2つの言葉で検索したい ごん 11/10/5(水) 14:56 質問[未読]
【69990】Re:2つの言葉で検索したい UO3 11/10/5(水) 16:36 回答[未読]
【70027】Re:2つの言葉で検索したい ごん 11/10/11(火) 17:09 お礼[未読]
【69997】Re:2つの言葉で検索したい kanabun 11/10/6(木) 12:05 発言[未読]
【69998】Re:2つの言葉で検索したい kanabun 11/10/6(木) 13:09 発言[未読]
【70026】Re:2つの言葉で検索したい ごん 11/10/11(火) 17:06 発言[未読]
【69999】Re:2つの言葉で検索したい UO3 11/10/6(木) 13:53 発言[未読]
【70000】Re:2つの言葉で検索したい kanabun 11/10/6(木) 14:55 発言[未読]
【70001】Re:2つの言葉で検索したい UO3 11/10/6(木) 17:05 発言[未読]
【70002】Re:2つの言葉で検索したい momo 11/10/7(金) 15:22 発言[未読]
【70003】Re:2つの言葉で検索したい UO3 11/10/7(金) 18:37 発言[未読]
【70004】Re:2つの言葉で検索したい ichinose 11/10/7(金) 19:14 発言[未読]
【70005】Re:2つの言葉で検索したい momo 11/10/7(金) 19:23 発言[未読]
【70009】Re:2つの言葉で検索したい kanabun 11/10/8(土) 0:13 発言[未読]
【70030】Re:2つの言葉で検索したい ごん 11/10/11(火) 18:00 お礼[未読]

【69938】2つの言葉で検索したい
質問  ごん  - 11/9/26(月) 9:35 -

引用なし
パスワード
   検索ダイアログボックスが開いて、”山本 鈴木”で検索すると、
”山本”あるいは”鈴木”が含まれるセルがアクティブになるようなマクロが作りたい。
山本と鈴木の両方が含まれる場合もアクティブになります。

動作は一般的な検索ダイアログボックスのように、次を検索ボタンを押すと最後まで検索していきます。

勝手なお願いですが、私にはハードルが高く、もし、簡単に作れるよという方が見えましたら、作成をお願いいたします。

難しいようでしたら、個別にコードのひとつひとつについて、質問していきたいと思います。

【69939】Re:2つの言葉で検索したい
回答  UO3  - 11/9/26(月) 10:07 -

引用なし
パスワード
   ▼ごん さん:

こんにちは

ダイアログボックスでの検索語の取得については、InputBox関数、InputBoxメソッド、あるいは
ユーザーフォームの利用等々があります。ここもお手伝い必要かどうかがわかりませんので
とりあえず、そこはできているということで、検索語をあたえて検索するコードです。

Test内の Call 検索(・・・・)の引数に、1つないしは2つの検索語を指定して
実行してみてください。

Sub Test()
  Call 検索("山本", "鈴木")
End Sub

Sub 検索(str1 As String, Optional str2 As Variant)
  Dim mystr As Variant
  Dim c As Range
  Dim v() As String
  
  With ActiveSheet.UsedRange
    If Not IsMissing(str2) Then
      ReDim v(1 To 4)
      v(1) = "*" & str1 & "*" & str2 & "*"
      v(2) = "*" & str2 & "*" & str1 & "*"
      v(3) = "*" & str1 & "*"
      v(4) = "*" & str2 & "*"
    Else
      ReDim v(1 To 1)
      v(1) = "*" & str1 & "*"
    End If
    
    For Each mystr In v
      Set c = .Cells.Find(What:=mystr, After:=.Cells(.Cells.Count), _
                    LookIn:=xlFormulas, LookAt:=xlWhole)
      If Not c Is Nothing Then Exit For
    Next
    
    If c Is Nothing Then
      MsgBox "指定した文字列は見当たりません"
    Else
      c.Activate
    End If
  End With
  
  Set c = Nothing
  
End Sub

【69943】Re:2つの言葉で検索したい
発言  kanabun  - 11/9/26(月) 18:44 -

引用なし
パスワード
   ▼ごん さん:こんにちは〜
ちょっと質問いいですか?

(1)
>”山本”あるいは”鈴木”が含まれるセルがアクティブになるような
検索する範囲はどこか1列ですか?
それとも複数列ですか?


(2)
> 次を検索ボタンを押すと最後まで検索していきます。
該当するセルが見つかるたびに、(そのセルをアクティブにして)一度STOPして、
[次を検索]ボタンを押して、次を検索する訳ですか?

該当するセルをすべて特定してから、それらのセルを選択するなり、
その後の処理をするという方法ではだめですか?

(1)の答えが「特定の1列」で、
(2)の答えが「すべての該当セルを表示」でいいのなら、一般機能の「データ」-
「フィルタ」-「フィルタオプションの設定」をつかうと、
意外と簡単なコードで済みそうです。

(3)
あと、複数列での検索のばあい、

  A      B      C
1 山本、鈴木
2        鈴木
3               山本
4

とあったばあい、まず[A1]セルの「山本、鈴木」をヒットさせ、
つぎに [B2]セルの「鈴木」をヒットさせたいんですよね? (^^

【69948】Re:2つの言葉で検索したい
お礼  ごん  - 11/9/27(火) 19:34 -

引用なし
パスワード
   ▼UO3 さん:
回答ありがとうございます。

*を使って工夫すればよいのは分かりました。
後は自分で考えてみようと思います。

【69951】Re:2つの言葉で検索したい
発言  ごん  - 11/9/27(火) 20:39 -

引用なし
パスワード
   ▼kanabun さん: レスありがとうございます。


>(1)
>>”山本”あるいは”鈴木”が含まれるセルがアクティブになるような
>検索する範囲はどこか1列ですか?
>それとも複数列ですか?

全部のセルが対象になります。


>(2)
>> 次を検索ボタンを押すと最後まで検索していきます。
>該当するセルが見つかるたびに、(そのセルをアクティブにして)一度STOPして、
>[次を検索]ボタンを押して、次を検索する訳ですか?

そうですよ。


>該当するセルをすべて特定してから、それらのセルを選択するなり、
>その後の処理をするという方法ではだめですか?

特に処理をする訳ではなく、該当セルがあるかどうかを確認することが
目的のため、一度STOPすることが理想です。


>(1)の答えが「特定の1列」で、
>(2)の答えが「すべての該当セルを表示」でいいのなら、一般機能の「データ」-
>「フィルタ」-「フィルタオプションの設定」をつかうと、
>意外と簡単なコードで済みそうです。

今回の目的に対して、この方法が使えないので質問しました。

>(3)
>あと、複数列での検索のばあい、
>
>  A      B      C
>1 山本、鈴木
>2        鈴木
>3               山本
>4
>
>とあったばあい、まず[A1]セルの「山本、鈴木」をヒットさせ、
>つぎに [B2]セルの「鈴木」をヒットさせたいんですよね? (^^

おっしゃる通りです。
よろしくお願いします。

【69952】Re:2つの言葉で検索したい
発言  UO3  - 11/9/28(水) 9:18 -

引用なし
パスワード
   ▼ごん さん:

おはようございます。
kanabunさんに整理いただいたことと、ごんさんの確認レスで、要件をかなりクリアに
理解できました。
あわせて、私がアップしたコードで、2つのワード指定時に4種類もの組合せで検索しているという
【お馬鹿な部分】にも気がつきました。

対処案については、kanabunさんはじめ、回答者の方々からもアップされると思いますが
時間が取れればユーザーフォームを使ったコードを考えてみたいと思っています。

【69953】Re:2つの言葉で検索したい
質問  ごん  - 11/9/28(水) 9:41 -

引用なし
パスワード
   ▼UO3 さん:
回答ありがとうございます。

コードを以下のように変更することで、それらしい動きをするようになりましたが、
たとえば、”山本”というセルが2つあった場合、一つ目のセルしか検索してくれません。

一つ目の”山本”がヒットすると、”山本”の検索はそこで終わって、”鈴木”の検索に移ってしまいます。
全ての”山本”を検索するためにはどのように変更すれば良いのでしょうか?


    For Each mystr In v
  
      Set c = .Cells.Find(What:=mystr, After:=.Cells(.Cells.Count), _
                    LookIn:=xlFormulas, LookAt:=xlWhole)
      
      If Not c Is Nothing Then
        c.Activate                  '←追加
        MsgBox c.Value              '←追加
      End If
      'If Not c Is Nothing Then Exit For   ←削除
    Next

【69954】Re:2つの言葉で検索したい
発言  ごん  - 11/9/28(水) 9:48 -

引用なし
パスワード
   ▼UO3 さん:
おはようございます。
すみません、行き違いで、また、新たな質問をしたところです。

確かに4種類は不要ですね。
私も今まで気づきませんでした。

ダイアログから作るのは、本当に時間があるときで結構ですし、
出来なくても構いませんので、気が向けばお願いしますくらいの
レベルで受け取ってください。

【69955】Re:2つの言葉で検索したい
回答  UO3  - 11/9/28(水) 11:48 -

引用なし
パスワード
   ▼ごん さん:

FindとFindNextを組み合わせてなんとかしたいと思っていたんですが、もう頭の中が破裂しそうで(?)
ちょっとださいですが、素直なというか、地道な、ループで。
Test2 あるいは Test3 をお試しください。

Sub Test2()
  Call 検索("山本", "鈴木")
End Sub

Sub Test3()
  Call 検索("山本")
End Sub

Private Sub 検索(ByVal str1 As String, Optional ByVal str2 As Variant)
  Dim c As Range
  Dim found As Boolean
  
  str1 = "*" & str1 & "*"
  If Not IsMissing(str2) Then
    str2 = "*" & str2 & "*"
  Else
    str2 = ""
  End If
  
  For Each c In ActiveSheet.UsedRange
    If Len(c.Value) > 0 Then
      If c.Value Like str1 Or c.Value Like str2 Then
        c.Activate
        If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit For
      End If
    End If
  Next
  
  If Not found Then MsgBox "検索対象のものはありません"
  
End Sub

【69956】Re:2つの言葉で検索したい
回答  UO3  - 11/9/28(水) 11:55 -

引用なし
パスワード
   ▼ごん さん:

この先、この 検索プロシジャをベースにダイアログと連動させようとした場合、
引数の構えを以下のようにしておいたほうが、使いやすそうです。

Sub Test4()
  Call 検索("山本", "鈴木")
End Sub

Sub Test5()
  Call 検索("山本", "")
End Sub

Sub Test6()
  Call 検索("", "山本")
End Sub

Private Sub 検索(ByVal str1 As String, ByVal str2 As String)
  Dim c As Range
  Dim found As Boolean
  
  str1 = "*" & str1 & "*"
  If Len(str2) > 0 Then str2 = "*" & str2 & "*"
  
  For Each c In ActiveSheet.UsedRange
    If Len(c.Value) > 0 Then
      If c.Value Like str1 Or c.Value Like str2 Then
        c.Activate
        If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit For
      End If
    End If
  Next
  
  If Not found Then MsgBox "検索対象のものはありません"
  
End Sub

【69957】Re:2つの言葉で検索したい
発言  ichinose  - 11/9/28(水) 13:42 -

引用なし
パスワード
   こんにちは。

FindメソッドとFindnextメソッドを使い、先に検索だけを行い、
見つかったセルをUnionメソッドを使って、
セル範囲の集合体にしておきます。

その後で、見つかったそのセル範囲を順次選択し、表示させてみては?

【69958】Re:2つの言葉で検索したい
発言  UO3  - 11/9/28(水) 14:51 -

引用なし
パスワード
   ▼ichinose さん:

>FindメソッドとFindnextメソッドを使い、先に検索だけを行い、
>見つかったセルをUnionメソッドを使って、
>セル範囲の集合体にしておきます。
>
>その後で、見つかったそのセル範囲を順次選択し、表示させてみては?

これはグッドですね!さすがです。
その方向で書いてみました。ただし、今までアップ済みのコードをなるべく流用しましたので
ちょっと、スッキリしないものになってますが、結果はでたようです。

Sub Test7()
  Call 検索("山本", "鈴木")
End Sub

Sub Test8()
  Call 検索("山本", "")
End Sub

Sub Test9()
  Call 検索("", "山本")
End Sub

Private Sub 検索(ByVal str1 As String, ByVal str2 As String)
  Dim c As Range
  Dim v(1 To 2)
  Dim myStr As Variant
  Dim ansR As Range
  Dim f As Range
  
  If Len(str1) > 0 Then str1 = "*" & str1 & "*"
  If Len(str2) > 0 Then str2 = "*" & str2 & "*"
  v(1) = str1
  v(2) = str2
  
  For Each myStr In v
    If Len(myStr) > 0 Then
      Set c = ActiveSheet.UsedRange.Find(What:=myStr, LookIn:=xlFormulas, LookAt:=xlWhole)
      If Not c Is Nothing Then
        Set f = c
        Do
          If ansR Is Nothing Then
            Set ansR = c
          Else
            Set ansR = Union(ansR, c)
          End If
          Set c = ActiveSheet.UsedRange.FindNext(c)
        Loop While c.Address <> f.Address
      End If
    End If
  Next
  MsgBox ansR.Address
  If ansR Is Nothing Then
    MsgBox "検索対象のものはありません"
  Else
    For Each c In ansR.Cells
      c.Activate
      If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit For
    Next
  End If
  
  Set ansR = Nothing
  Set c = Nothing
  Set f = Nothing
  
End Sub

【69959】Re:2つの言葉で検索したい
発言  UO3  - 11/9/28(水) 14:52 -

引用なし
パスワード
   ↑ MsgBox ansR.Address

 これはテスト確認用のコードですので削除願います。

【69989】Re:2つの言葉で検索したい
質問  ごん  - 11/10/5(水) 14:56 -

引用なし
パスワード
   ▼UO3 さん:
回答ありがとうございます。
期待通りの動きになりました。

また、質問があるのですが、今回は検索文字が2つでしたが、これが3つの時もあれば、4つの時もあるような可変の場合は、どうすれば良いのでしょうか?

検索したい文字はA1セルに書かれている条件でよいので、分かれば教えてください。

【69990】Re:2つの言葉で検索したい
回答  UO3  - 11/10/5(水) 16:36 -

引用なし
パスワード
   ▼ごん さん:

以下でお試しください。

A1に あああ いいい ううう といったように半角スペースで区切られた
複数の検索文字列が入っているという前提で。
(文字列の数は制限なし)


Sub 検索2()
  Dim c As Range
  Dim v As Variant
  Dim myStr As Variant
  Dim ansR As Range
  Dim f As Range
  Dim i As Long
  
  v = Split(Range("A1").Value) '半角スペースで区切られた検索文字列を取得
  For i = LBound(v) To UBound(v)
    v(i) = "*" & v(i) & "*"  'ワイルドカードに変更
  Next

  For Each myStr In v
    If Len(myStr) > 0 Then
      Set c = ActiveSheet.UsedRange.Find(What:=myStr, LookIn:=xlFormulas, LookAt:=xlWhole)
      If Not c Is Nothing Then
        Set f = c
        Do
          If ansR Is Nothing Then
            Set ansR = c
          Else
            Set ansR = Union(ansR, c)
          End If
          Set c = ActiveSheet.UsedRange.FindNext(c)
        Loop While c.Address <> f.Address
      End If
    End If
  Next
  MsgBox ansR.Address
  If ansR Is Nothing Then
    MsgBox "検索対象のものはありません"
  Else
    For Each c In ansR.Cells
      c.Activate
      If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit For
    Next
  End If
 
  Set ansR = Nothing
  Set c = Nothing
  Set f = Nothing
 
End Sub

【69997】Re:2つの言葉で検索したい
発言  kanabun  - 11/10/6(木) 12:05 -

引用なし
パスワード
   ▼ごん さん:
>▼UO3 さん:

>  A      B      C
>1 山本 鈴木
>2        鈴木
>3               山本
>4
>
[A1]セルに 「山本 鈴木」の入力があり、
表が上記のようであったばあい、
まず[B2]セルの「鈴木」をヒットさせ、
つぎに [C3]セルの「山本」をヒットさせたいんですよね? (^^

【69998】Re:2つの言葉で検索したい
発言  kanabun  - 11/10/6(木) 13:09 -

引用なし
パスワード
   単純に1セルづつ調べていったらどうなんでしょ?

Sub Step検索()
 Dim i&, j&, k&
 Dim v, s, sArry
 v = ActiveSheet.UsedRange.Value
 sArry = Split(Range("A1").Value)
 If UBound(sArry) < 0 Then Exit Sub
 For i = 1 To UBound(v)
   For j = 1 To UBound(v, 2)
     If i + j > 2 Then
      For Each s In sArry
       If InStr(1, v(i, j), s, vbTextCompare) > 0 Then
         Cells(i, j).Select
         If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit Sub
         Exit For
       End If
      Next
     End If
   Next
 Next

End Sub

【69999】Re:2つの言葉で検索したい
発言  UO3  - 11/10/6(木) 13:53 -

引用なし
パスワード
   ▼ごん さん:

kanabunさんからご指摘がありましたが、検索値の入っているA1と検索するシートは同じでしたね。(あたりまえですけど)

みつかったセルからA1を除外します。

Sub 検索3()
  Dim c As Range
  Dim v As Variant
  Dim myStr As Variant
  Dim ansR As Range
  Dim f As Range
  Dim i As Long
 
  v = Split(Range("A1").Value) '半角スペースで区切られた検索文字列を取得
  For i = LBound(v) To UBound(v)
    v(i) = "*" & v(i) & "*"  'ワイルドカードに変更
  Next

  For Each myStr In v
    If Len(myStr) > 0 Then
      Set c = ActiveSheet.UsedRange.Find(What:=myStr, LookIn:=xlFormulas, LookAt:=xlWhole)
      If Not c Is Nothing Then
        Set f = c
        Do
          If c.Address(False, False) <> "A1" Then
            If ansR Is Nothing Then
              Set ansR = c
            Else
              Set ansR = Union(ansR, c)
            End If
          End If
          Set c = ActiveSheet.UsedRange.FindNext(c)
        Loop While c.Address <> f.Address
      End If
    End If
  Next
  MsgBox ansR.Address
  If ansR Is Nothing Then
    MsgBox "検索対象のものはありません"
  Else
    For Each c In ansR.Cells
      c.Activate
      If MsgBox("検索を続けますか?", vbYesNo) = vbNo Then Exit For
    Next
  End If

  Set ansR = Nothing
  Set c = Nothing
  Set f = Nothing

End Sub

【70000】Re:2つの言葉で検索したい
発言  kanabun  - 11/10/6(木) 14:55 -

引用なし
パスワード
   ▼UO3 さん:
>kanabunさんからご指摘がありましたが、

ぼくの発言の主旨は、
たとえば
A列に

1 鈴木 山本
2 山本
3 鈴木
4 山本
5 鈴木
6 山本
: :
とあったばあい、UO3さんの Find〜FindNextの方法では
順次検索が、

1回目 : 鈴木、鈴木、鈴木.... の検索
2回目 : 山本、山本、山本... の検索

のようになるため、結果として
[A3]鈴木
[A5]鈴木
[A2]山本
[A4]山本
[A6]山本
 :
と確認していくことになっていることです。
たとえUnionで見つかったセルをため込んでおいても。

ヒットする順番は
[A2]山本
[A3]鈴木
[A4]山本
[A5]鈴木
[A6]山本
 :
というセル順でないといけないのでは?

【70001】Re:2つの言葉で検索したい
発言  UO3  - 11/10/6(木) 17:05 -

引用なし
パスワード
   ▼kanabun さん:

ご指摘のポイント理解しました。
そうですねぇ。
セル基準で、検索値をチェックするループがまっとうな方式ですね。

むりやり、現在の私の構えで(検索値基準で)やるなら、Unionしておいたアドレスを
最後にばらばらにして、並び替えて、その結果をもとにセル選択させるということが必要になるんですね。
しかも、たとえそうしても、Unionの結果、連続領域のAreaが存在した場合、必ずしも
妥当な順序にはなりませんし。

▼ごんさん

ということなので、私のコードは捨てて、kanabunさんの方式をどうぞ。

【70002】Re:2つの言葉で検索したい
発言  momo  - 11/10/7(金) 15:22 -

引用なし
パスワード
   ▼UO3 さん:

Findメソッドでも列ごとに検索したものを
UnionでRow順にしてCollectionにでも入れてあげれば出来そうですよ^^

Sub test()
Dim tbl   As Variant
Dim FindStr As Variant
Dim myColumn As Range
Dim FoundRng As Range
Dim UnionRng As Range
Dim myC   As New Collection

With ActiveSheet
 tbl = Split(.Range("A1").Value, " ")
 For Each myColumn In .UsedRange.Columns
  For Each FindStr In tbl
   Set FoundRng = myColumn.Find(FindStr, myColumn.Cells(1), _
           xlValues, xlPart, xlByRows, xlNext)
   If Not FoundRng Is Nothing Then
    FirstAddress = FoundRng.Address
    Do
     If Application.Intersect(FoundRng, .Range("A1")) Is Nothing Then
      If UnionRng Is Nothing Then
       Set UnionRng = FoundRng
      Else
       Set UnionRng = Application.Union(UnionRng, FoundRng)
      End If
     End If
     Set FoundRng = myColumn.FindNext(FoundRng)
    Loop Until FirstAddress = FoundRng.Address
   End If
  Next FindStr
  If Not UnionRng Is Nothing Then
   For Each myRng In UnionRng
    myC.Add myRng
   Next myRng
   Set UnionRng = Nothing
  End If
 Next myColumn
End With
If myC.Count > 0 Then
 For Each FoundRng In myC
  MsgBox "次へ"
  FoundRng.Select
 Next FoundRng
Else
 MsgBox "見つかりません"
End If
End Sub

【70003】Re:2つの言葉で検索したい
発言  UO3  - 11/10/7(金) 18:37 -

引用なし
パスワード
   ▼momo さん:

おせわになります。

A1 に aaa bbb といれまして、

A列、B列、C列に 適当に aaa や bbb や aaa bbb といったものをいれ
アップいただいたコードを試してみました。

A列については、順調に上から順に選択が行われましたがB列では、まず aaa が
その後、もどって bbb が選択されました。

私も、これから、あらためてコードをおいかけてみます。

【70004】Re:2つの言葉で検索したい
発言  ichinose  - 11/10/7(金) 19:14 -

引用なし
パスワード
   こんばんは。

>FindメソッドとFindnextメソッドを使い、先に検索だけを行い、
>見つかったセルをUnionメソッドを使って、
>セル範囲の集合体にしておきます。


と言ってしまったので、Unionでの順序の違い程度は、いいじゃない と、
思っていたので良いと思ってましたが、駄目ですか・・・。
だったら、どっかで並べ替えるしかないですねえ


新規ブックにて

標準モジュール(Module1)に
既作のFindメソッドの汎用プロシジャー

'=================================================================
Option Explicit
Function get_findcell(Optional ByVal f_v As Variant = "", _
           Optional ByVal rng As Range = Nothing, _
           Optional ByVal strng As Range = Nothing, _
           Optional ByVal alookin As XlFindLookIn = -4163, _
           Optional ByVal alookat As XlLookAt = 1, _
           Optional ByVal aso As XlSearchOrder = 1, _
           Optional ByVal asd As XlSearchDirection = 1, _
           Optional ByVal mc As Boolean = False, _
           Optional ByVal mb As Boolean = True) As Range
'指定された値でセル範囲を検索し、該当するセルを取得する
'input : f_v 検索する値
'    rng 検索する範囲
'    strng 検索開始するセル(実際には、このセルの次から検索する)
'    alookin 検索対象 xlvalues,xlformulas,xlcomments
'    alookat: :検索方法 1-完全一致 2-部分一致
'    aso : 検索順序 1 行 2 列
'    asd : 検索方向 1 Xlnext 2 XlPrevious
'    mc  : 大文字・小文字の区別 False しない True する
'    mb  : 半角と全角を区別   True する  False しない
'output:get_findcell 見つかったセル(見つからなかったときはNothingが返る)
  Static 検索範囲 As Range
  Static 最初に見つかったセル As Range
  Static 直前に見つかったセル As Range
  Static 検索方向 As XlSearchDirection
  Dim app As Object
  If Not rng Is Nothing Then
    If Val(Application.Version) > 9 Then
     Set app = Application
     app.FindFormat.Clear
     Set app = Nothing
    End If
    Set 検索範囲 = rng
    If strng Is Nothing Then
     If asd = 1 Then
       Set strng = 検索範囲.Cells(検索範囲.Rows.Count, 検索範囲.Columns.Count)
     Else
       Set strng = 検索範囲.Cells(1, 1)
     End If
   
    End If
    検索範囲.Parent.Columns(1).Find ""
  End If
  If f_v <> "" Then
   
    Set get_findcell = 検索範囲.Find(f_v, strng, alookin, alookat, aso, asd, mc, mb)
    If Not get_findcell Is Nothing Then
     Set 最初に見つかったセル = get_findcell
     Set 直前に見つかったセル = get_findcell
     検索方向 = asd
    End If
  Else
    If 検索方向 = xlNext Then
     Set get_findcell = 検索範囲.FindNext(直前に見つかったセル)
    Else
     Set get_findcell = 検索範囲.FindPrevious(直前に見つかったセル)
    End If
    If Not get_findcell Is Nothing Then
     If get_findcell.Address = 最初に見つかったセル.Address Then
       Set get_findcell = Nothing
     Else
       Set 直前に見つかったセル = get_findcell
     End If
    End If
  End If
End Function


別の標準モジュール(Module2)に

'=================================================================
Sub samp1()
  Dim g0 As Long
  Dim ans As Variant
  Dim ret As Long
  Dim mes As Variant
  Dim g1 As Long
  mes = Array("", "データの終わりです", "データの始めです")
  
  ans = 検索EX(ActiveSheet.UsedRange, Array("竹内結子", "坂井真紀", "星奈々")) 'この配列に複数の検索データを記述
  If TypeName(ans) <> "Boolean" Then
    g1 = 0
    g0 = LBound(ans, 1)
    ret = vbYes
    Do Until ret = vbCancel
     Cells(ans(g0, 1), ans(g0, 2)).Select
     ret = MsgBox(mes(g1) & vbCrLf & _
          "はい    次のデータ" & vbCrLf & _
          "いいえ   前のデータ" & vbCrLf & _
          "キャンセル 検索の終わり", vbYesNoCancel)
     If ret = vbYes Then
       If g0 + 1 > UBound(ans, 1) Then
        g1 = 1
       Else
        g1 = 0
        g0 = g0 + 1
       End If
     ElseIf ret = vbNo Then
       If g0 - 1 < LBound(ans, 1) Then
        g1 = 2
       Else
        g0 = g0 - 1
        g1 = 0
       End If
     End If
          
    Loop
  End If
End Sub
'==============================================================
Function 検索EX(rng As Range, f_str As Variant) As Variant
  Dim dic As Object
  Dim fr As Range
  Dim g0 As Long
  Dim wk As Variant
  検索EX = False
  Set dic = CreateObject("scripting.dictionary")
  For g0 = LBound(f_str) To UBound(f_str)
    Set fr = get_findcell(f_str(g0), rng, , xlValues, xlPart, xlByRows, xlNext)
    Do Until fr Is Nothing
     dic(Join(Array(fr.Row, fr.Column), " ")) = Array(fr.Row, fr.Column)
     Set fr = get_findcell()
    Loop
  Next
  If dic.Count > 0 Then
    Application.ScreenUpdating = False
    With Workbooks.Add
     With .Worksheets(1)
       With .Range(.Cells(1, "a"), .Cells(dic.Count, "a")).Resize(, 2)
        .Value = Application.Transpose(Application.Transpose(dic.items))
        With .Resize(, 2)
          .Sort Key1:=Range("A1"), Order1:=xlAscending, Key2:=Range("B1") _
            , Order2:=xlAscending, Header:=xlGuess, OrderCustom:=1, MatchCase:= _
            False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin, DataOption1:= _
            xlSortNormal, DataOption2:=xlSortNormal
          検索EX = .Value
        End With
       End With
     End With
     .Close False
    End With
    Application.ScreenUpdating = True
  End If
End Function


別の標準モジュール(Module3)に
サンプルデータ作成プロシジャー

Sub mk_datasmp()
  Range("a1").Value = "竹内結子"
  Range("c1").Value = "星奈々"
  Range("i21").Value = "竹内結子 星奈々"
  Range("ik65512").Value = "坂井真紀"
  Range("iv65536").Value = "竹内結子"
  Range("a1").Select
End Sub


操作手順

mk_datasmpを実行してください。サンプルデータを表示します。

samp1を実行してください。
はいで 順検索 いいえで 逆検索  キャンセルで 検索終了です。

【70005】Re:2つの言葉で検索したい
発言  momo  - 11/10/7(金) 19:23 -

引用なし
パスワード
   ▼UO3 さん:
>A列については、順調に上から順に選択が行われましたがB列では、まず aaa が
>その後、もどって bbb が選択されました。

あ〜私の勘違い
Unionは連続範囲は並べ替えてくれるけどAreaはダメなんでした。
うっかりしてました・・・すみません>_<

【70009】Re:2つの言葉で検索したい
発言  kanabun  - 11/10/8(土) 0:13 -

引用なし
パスワード
   ▼ごん さん:
>>(3)
>>あと、複数列での検索のばあい、
>>
>>  A      B      C
>>1 山本、鈴木
>>2        鈴木
>>3               山本
>>4
>>
>>とあったばあい、まず[A1]セルの「山本、鈴木」をヒットさせ、
>>つぎに [B2]セルの「鈴木」をヒットさせたいんですよね? (^^
>
>おっしゃる通りです。


いっそ、該当セル、全部選択してはだめですか?

Sub FC検索()
  Dim c As Range
  Dim ss, s
  Dim ok As Boolean
  ss = Split(Range("A1").Value)
  With ActiveSheet.UsedRange
    .FormatConditions.Delete
    For Each c In .Cells
     If ok Then
      For Each s In ss
        If InStr(c.Value, s) Then
           c.FormatConditions.Add xlCellValue, xlEqual _
              , Formula1:="="" & s & """
          Exit For
        End If
      Next
     Else
      ok = True
     End If
    Next
    On Error Resume Next
    .SpecialCells(xlCellTypeAllFormatConditions).Select
    On Error GoTo 0
  End With
End Sub

上のプログラム実行すると、[A1]セルに書いてあるスペース区切りの
検索値を含むセルが すべて選択されます。
そして、一番最初のセルがアクティブになります。
TABキーまたは ENTERキーを押していけば、次の、その次の該当セル
にジャンプできます。

【70026】Re:2つの言葉で検索したい
発言  ごん  - 11/10/11(火) 17:06 -

引用なし
パスワード
   ▼kanabun さん:

レスありがとうございます。

>>  A      B      C
>>1 山本 鈴木
>>2        鈴木
>>3               山本
>>4
>>
>[A1]セルに 「山本 鈴木」の入力があり、
>表が上記のようであったばあい、
>まず[B2]セルの「鈴木」をヒットさせ、
>つぎに [C3]セルの「山本」をヒットさせたいんですよね? (^^


本当はダイアログボックスに検索文字を入れるのですが、ここでの質問は、簡略化してA1セルに検索文字を入れてという、前提にしました。

したがって、Aセルもヒットして構いません。

【70027】Re:2つの言葉で検索したい
お礼  ごん  - 11/10/11(火) 17:09 -

引用なし
パスワード
   ▼UO3 さん:
回答ありがとうございます。
お礼が遅くなりました。
このコードでばっちりです。
でも、なぜかやり取りが続いているようですね。

そのやり取りは今から読んでみます。

【70030】Re:2つの言葉で検索したい
お礼  ごん  - 11/10/11(火) 18:00 -

引用なし
パスワード
   皆さん 色々回答ありがとうございます。

色々考えていて、御礼が遅くなっている間に、色々なやり取りがされているとは知りませんでした。

今回、最初は、レスを頂いた投稿そのものに対応したお礼を書いていましたが、私のお礼が遅くなったため、ツリー表示で全体を見るとやり取りがぐじゃぐじゃになってますね。

まさに今回の検索の順番の話のようです。

前置きが長くなりましたが、
皆さんから教えていただいたコードを試してみましたが、挙動が意外とつかみ辛く(申し訳ないです)どれが良いということは特にありません。

本来の目的は、データベースのような使い方をしているエクセルファイルがありまして、その中から、VBAについて書かれているセルを探そうとしたときに、VBAで検索してもなにもヒットしないと、あれおかしいな?マクロという言葉で書いたかな?ということで今度はマクロという言葉で検索します。これでもヒットしないと、プログラムで検索してみようということで、面倒くさいので、最初から3つの言葉で検索できるといいなと思いました。

したがいまして、まったく別の言葉ではなく、同じ意味の言葉3つで検索することになるので、検索される順番は特に問いません。

2089 / 13645 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free