Excel VBA質問箱 IV

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

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


18727 / 76732 ←次へ | 前へ→

【63443】Re:リスト削除
発言  Hirofumi  - 09/11/4(水) 13:26 -

引用なし
パスワード
   「こもと さん」では有りませんが
こんなのでは

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

2 hits

【63411】リスト削除 たつ 09/11/2(月) 14:26 質問
【63413】Re:リスト削除 Yuki 09/11/2(月) 15:07 発言
【63415】Re:リスト削除 たつ 09/11/2(月) 15:21 発言
【63414】Re:リスト削除 こもと 09/11/2(月) 15:17 発言
【63417】Re:リスト削除 たつ 09/11/2(月) 15:52 質問
【63419】Re:リスト削除 こもと 09/11/2(月) 16:56 発言
【63418】Re:リスト削除 たつ 09/11/2(月) 16:54 質問
【63421】Re:リスト削除 こもと 09/11/2(月) 17:09 発言
【63431】Re:リスト削除 たつ 09/11/3(火) 14:45 お礼
【63442】Re:リスト削除 たつ 09/11/4(水) 8:39 質問
【63443】Re:リスト削除 Hirofumi 09/11/4(水) 13:26 発言
【63444】Re:リスト削除 たつ 09/11/4(水) 15:16 質問
【63445】Re:リスト削除 Hirofumi 09/11/4(水) 15:43 回答
【63447】Re:リスト削除 たつ 09/11/5(木) 11:25 お礼
【63446】Re:リスト削除 kanabun 09/11/4(水) 16:07 発言
【63425】Re:リスト削除 SS 09/11/2(月) 20:05 発言
【63432】Re:リスト削除 たつ 09/11/3(火) 14:47 お礼
【63426】Re:リスト削除 Hirofumi 09/11/2(月) 20:15 回答
【63427】Re:リスト削除 Hirofumi 09/11/3(火) 12:29 回答
【63433】Re:リスト削除 たつ 09/11/3(火) 14:49 お礼
【63428】Re:リスト削除 arajin 09/11/3(火) 14:20 回答
【63429】Re:リスト削除 arajin 09/11/3(火) 14:25 回答
【63434】Re:リスト削除 たつ 09/11/3(火) 14:51 お礼

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