- ベストアンサー
エクセルマクロで複数条件と部分一致検索の方法
- エクセルのマクロを使用して、複数の条件と部分一致検索を行う方法について教えてください。
- 具体的な処理の流れは次のとおりです。まず、Sheet2の検索値A1に部分一致する値をSheet1のA列から選びます。次に、選ばれた値とSheet2のB1が完全一致する値をSheet1のB列から選びます。最後に、選ばれた値の行のC列の値を転記します。
- 部分一致の後の完全一致の複合的なコードの組み方がわからないため、繰り返し処理(ForやLoop)の理解が必要です。Windows XPとOffice 2003を使用しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>例えば、xlpart、Match、Index、Offset を使い… そういったやり口ではない,簡単な方法で。 #ただし簡単のため「複数ヒットの場合の採用基準」を変更しています #簡単のため,シート1,2ともに「1行目にタイトル行」「2行目から実データ」というレイアウトを仮定します。常識的な作表と判断しています。 サンプル: Sub macro1() Dim h As Range Application.ScreenUpdating = False ’シート2のデータを巡回 For Each h In Worksheets("Sheet2").Range("A2:A" & Worksheets("Sheet2").Range("A65536").End(xlUp).Row) ’該当データの抽出 Worksheets("Sheet1").Range("A:B").AutoFilter field:=1, Criteria1:="*" & h & "*" Worksheets("Sheet1").Range("A:B").AutoFilter field:=2, Criteria1:=h.Offset(0, 1) ’転記 h.Offset(0, 2) = Worksheets("Sheet1").Range("A65536").End(xlUp) h.Offset(0, 3) = Worksheets("Sheet1").Range("C65536").End(xlUp) Next Worksheets("Sheet1").AutoFilterMode = False Application.ScreenUpdating = True End Sub
その他の回答 (3)
- merlionXX
- ベストアンサー率48% (1930/4007)
順列組み合わせ方式、オートフィルタ方式と出ているようですので、検索方式の一例を書きます。 Sub test01() Dim i As Long Dim ws(1 To 2) As Worksheet Dim fnd As Range Dim fa As String '以上変数宣言 Set ws(1) = Sheets("Sheet1") Set ws(2) = Sheets("Sheet2") Application.ScreenUpdating = False '画面更新停止 For i = 1 To ws(2).Cells(Rows.Count, "A").End(xlUp).Row 'Sheet2検査値の数取得 Set fnd = ws(1).Columns("A:A").Find(What:=ws(2).Cells(i, 1).Value, LookAt:=xlPart) '部分一致検索 If Not fnd Is Nothing Then 'あれば fa = fnd.Address 'アドレスを控える Do '繰り返す Set fnd = ws(1).Columns("A:A").FindNext(fnd) If fnd.Offset(, 1).Value = ws(2).Cells(i, 2).Value Then '条件が一致すれば With ws(2).Cells(i, 3) '転記 .Value = fnd.Text .Offset(, 1) = fnd.Offset(, 2).Text End With End If Loop While Not fnd Is Nothing And fa <> fnd.Address End If Next i Application.ScreenUpdating = True '画面更新停止解除 End Sub
お礼
merlionXX様へ 前の方のおっしゃるFindを使ってご教示いただきありがとうございます。すぐ動きました。 相当なハイレベルなので、勉強の題材にし、1行1行理解しようと思います。どのようにしたらスラスラかけるようになるのでしょうか~。やはり頭の作りの違いでしょうか(笑) ご教示ありがとうございます。
- imogasi
- ベストアンサー率27% (4737/17069)
検索というのはエクセルのSheet1のデータの全行を対象にしないとならないと思います。 便利なような関数なども、裏では全データを対象にしているはず。対象が既にメモリ上データ(関数など)とシート上のデータに違いはあるが。 ですから最終行までのA列全セル繰り返しで良いでしょう。 Sub test01() Set sh1 = Worksheets("Sheet1") Set sh2 = Worksheets("Sheet2") d = sh1.Range("A65536").End(xlUp).Row y = sh2.Range("A1") z = sh2.Range("B1") '-- For i = 2 To d x = sh1.Cells(i, "A") p1 = InStr(x, y) 'yが含まれるか If p1 <> 0 Then p2 = InStr(x, z) 'zが含まれるか If p2 <> 0 Then sh1.Cells(1, "C") = sh1.Cells(i, "A") Exit For '1つ見つかったら打ち切り End If End If Next i End Sub 質問はしっかり書けていると思うが、全般の構想力が弱いため、質問文の表現が長くなりすぎとおもう。 もっと簡単なことでは。 もっと色々上達し、上記に飽き足らなくなったら、Findなどを使えないか考えたら良い。 Findは初心者には難しいと思っている。 B1に全部一致を求めるならB1と等しいと聞く(判別する)か、長さが一致するかを聞けばよいだろう。
お礼
すぐ教えていただきありがとうございます。試していますが、焦っているのかまだ動きません。もう少し解読してみたいと思います。自分のやり方が悪いのかもしれません。 >p1 = InStr(x, y) 'yが含まれるか のInStrについてわからないので後日調べてみます。 また、鋭いご指摘にも感謝いたします。imogasi様はどれくらいのご経験なのでしょう。ベストアンサーにしたいのですが、ベストアンサーが1つなので困りました。
- tom04
- ベストアンサー率49% (2537/5117)
こんにちは! こんな感じですかね? 複数該当する場合は上位を表示ということですので・・・ Sub test() Dim i, j As Long Dim ws1, ws2 As Worksheet Set ws1 = Worksheets("sheet1") Set ws2 = Worksheets("sheet2") For j = ws2.Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1 For i = ws1.Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1 If ws1.Cells(i, 1) Like "*" & ws2.Cells(j, 1) & "*" And ws1.Cells(i, 2) = ws2.Cells(j, 2) Then With ws2.Cells(j, 3) .Value = ws1.Cells(i, 1) .Offset(, 1) = ws1.Cells(i, 3) End With End If Next i Next j End Sub For~Next を使っていますので時間がかかるかもしれません。 他によい方法があればごめんなさいね。m(__)m
お礼
すぐ教えていただきありがとうございます。試していますが、焦っているのかまだ動きません。もう少し解読してみたいと思います。自分のやり方が悪いのかもしれません。勉強して別の立場で、このように教えれるレベルになりたいと思います。tom04様はどれくらいのご経験なのでしょう。ベストアンサーにしたいのですが、ベストアンサーが1つなので困りました。
お礼
keithin様はどれくらいのご経験なのでしょうか。どうやったら、このように書けるか勉強方法を教えていただきたいくらいです。こちらは1ヶ月の経験です。すぐ動かすことができました。1行1行理解していきたいと思います。ありがとうございます。