| 
    
     |  | 「こもと さん」では有りませんが こんなのでは
 
 Sub test_2()
 
 Const strPrefix As String = "CA"
 
 Dim myD As Object
 Dim i As Long, tbl
 '  Dim MyLen As Integer
 '  Dim MyCA As Variant
 
 Set myD = CreateObject("Scripting.Dictionary")
 
 '========================================================================
 tbl = Worksheets("Sheet2").Range("A1").CurrentRegion.Columns("A").Value
 For i = 1 To UBound(tbl)
 myD.Add tbl(i, 1), ""
 Next i
 
 '  With Worksheets(2)
 With Worksheets("Sheet1")
 tbl = .Range("A2").CurrentRegion.Columns("A:B").Value
 For i = 1 To UBound(tbl)
 If myD.exists(tbl(i, 1)) Then
 If tbl(i, 2) Like strPrefix & "*" Then
 tbl(i, 2) = Mid(tbl(i, 2), Len(strPrefix) + 1)
 End If
 If Not myD.exists(tbl(i, 2)) Then
 myD.Add tbl(i, 2), ""
 End If
 End If
 Next i
 For i = UBound(tbl) To 1 Step -1
 If myD.exists(tbl(i, 1)) Then
 .Range("C" & i).Value = "X"
 End If
 Next i
 End With
 
 End Sub
 
 なお、
 >2行 |   BBB   CABBB ←削除(CAから始まる為、BBBがキーとなってます)
 は、親と次を指し示す子が同じなのは、データ的に変なのでは?
 
 また、私のコードでは以下の様に成ります
 前回、書き忘れましたが私のコードでは、
 Sheet1、Sheet2共に列見出しが有る物とします
 (もし列見出しが無い場合は、上に1行列見出しを入れて下さい)
 また、今回は、削除の確認の為オートフィルタが最後に掛かって終わる様にして有ります
 
 Option Explicit
 
 Public Sub Sample_3()
 
 ' オートフィルタに因る削除データの表示版
 
 '◆Listのデータ列数(A列〜D列)
 Const clngColumns As Long = 4
 
 '◆Listの中の親と成る列位置(基準列からの列Offset:1列目)
 Const clngKey1 As Long = 0
 '◆Listの中の子と成る列位置(基準列からの列Offset:2列目)
 Const clngKey2 As Long = 1
 
 'B列に付く可能性の有る接頭子
 Const cstrPrefix As String = "CA"
 
 Dim i As Long
 Dim j As Long
 Dim lngRows As Long
 Dim rngList As Range
 Dim rngDelete As Range
 Dim vntList As Variant
 Dim vntDelete As Variant
 Dim vntFlags() As Variant
 Dim lngCount As Long
 Dim strProm As String
 
 Dim sngTime1 As Single
 Dim sngTime2 As Single
 
 sngTime2 = Timer
 
 '◆Listの先頭セル位置を基準とする(先頭列の列見出しのセル位置)
 Set rngList = Worksheets("Sheet1").Cells(1, "A")
 
 '◆結果出力の先頭セル位置を基準とする(先頭列の列見出しのセル位置)
 Set rngDelete = Worksheets("Sheet2").Cells(1, "A")
 
 With rngDelete
 '行数の取得
 lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row
 If lngRows <= 0 Then
 strProm = "データが有りません"
 GoTo Wayout
 End If
 '列データを配列に取得
 vntDelete = .Offset(1).Resize(lngRows + 1).Value
 End With
 
 With rngList
 If .Parent.FilterMode Then
 .Parent.UsedRange.AutoFilter
 End If
 '行数の取得
 lngRows = .Offset(Rows.Count - .Row, clngKey1).End(xlUp).Row - .Row
 If lngRows <= 0 Then
 strProm = "データが有りません"
 GoTo Wayout
 End If
 '親子データを格納する配列を確保
 ReDim vntList(0 To 1)
 '親列データを配列に取得
 vntList(0) = .Offset(1, clngKey1).Resize(lngRows + 1).Value
 '子列データを配列に取得
 vntList(1) = .Offset(1, clngKey2).Resize(lngRows + 1).Value
 '削除フラグを格納する配列を確保
 ReDim vntFlags(1 To lngRows, 1 To 1)
 End With
 
 '削除行の抽出(Sheet2のA列全て)
 For i = 1 To UBound(vntDelete, 1) - 1
 DataDelete vntDelete(i, 1), vntList, 1, vntFlags(), lngCount, cstrPrefix
 Next i
 
 With rngList
 '削除行が有るなら
 If lngCount > 0 Then
 'フラグを出力
 .Offset(, clngColumns).EntireColumn.ClearComments
 .Offset(, clngColumns).Value = "削除フラグ"
 .Offset(1, clngColumns).Resize(lngRows).Value = vntFlags
 'フラグをKeyとしてオートフィルタを掛ける
 .Resize(lngRows + 1, clngColumns + 1).AutoFilter _
 Field:=clngColumns + 1, Criteria1:="=×", Operator:=xlAnd
 End If
 End With
 
 strProm = "処理が完了しました"
 
 Wayout:
 
 Set rngList = Nothing
 Set rngDelete = Nothing
 
 sngTime1 = Timer
 
 MsgBox strProm & vbLf & (sngTime1 - sngTime2), vbInformation
 
 End Sub
 
 Private Sub DataDelete(vntKey As Variant, _
 vntList As Variant, _
 lngRow As Long, _
 vntFlags() As Variant, _
 lngCount As Long, _
 strPrefix As String)
 
 'A列最終行まで繰り返し
 Do Until IsEmpty(vntList(0)(lngRow, 1))
 '探索KeyとA列の値が同じなら
 If vntKey = vntList(0)(lngRow, 1) Then
 'A列と同位のB列の値に"CA"が付いている場合
 If vntList(1)(lngRow, 1) Like strPrefix & "*" Then '★追加
 '"CA"を取り除いた値の変換
 vntList(1)(lngRow, 1) = Mid(vntList(1)(lngRow, 1), Len(strPrefix) + 1) '★追加
 End If '★追加
 '削除フラグに削除記号がないなら
 If IsEmpty(vntFlags(lngRow, 1)) Then '★追加
 'フラグを立てる
 vntFlags(lngRow, 1) = "×" '★変更
 '削除数を更新
 lngCount = lngCount + 1
 End If '★追加
 'もし、A列と同位のB列の値がA列の値と等しくないなら(データ不良を避ける)
 If vntList(0)(lngRow, 1) <> vntList(1)(lngRow, 1) Then
 'B列の値を探しに再帰呼び出しを行う
 DataDelete vntList(1)(lngRow, 1), vntList, 1, vntFlags(), lngCount, strPrefix
 End If
 End If
 '次の行に更新
 lngRow = lngRow + 1
 Loop
 
 End Sub
 
 
 |  |