優先度の判定
・CB列の数字が小さい行を優先する
・CB列の数字が同じ場合、A列の数字が大きい行を優先する
CB列の先頭一文字×10000-A列の値 を比較するようにすればいいでしょう(A列の値が4桁以内の場合、桁数が多い場合はそれに合わせて×数値を増やします)。
辞書機能を使って既存の行と現在の行での比較(2行分の比較)しかできず、どうやっても
3行以上の比較が分からなかったので質問しました。
3行以上の比較をする必要はないのでは。
最終行から上に移動しながら、
辞書のキーにCA列の値、アイテムに行番号を登録していく、
CA列の値がキーにすでに存在する場合は、アイテムの行と現行の上記の比較値を比べて、比較値が大きいほうの行を削除して、小さいほうの行番号をアイテムに格納する。
これを先頭行まで繰り返せば、比較値の最小の行のみ残ります。
これで希望の結果に得られます。
訂正
上記のロジックですが、行番号を格納してそれを元に削除すると、削除することによってそれ以降の行が上に移動するので、格納した行番号とずれてしまいます。
実際にコード化して気が付きました。
ということで、下記のロジックに訂正します。
最終行から上に移動しながら、
辞書のキーにCA列の値、アイテムに比較値を登録していく、
CA列の値がキーにすでに存在する場合は、小さいほうの比較値をアイテムに格納する。
これを先頭行まで繰り返すとキーに対応する優先度のもっとも高い比較値が格納されます。
再度、最終行から上に移動しながら、
現在行の比較値と辞書の比較値(もっとも優先度の高い値)が一致しない行を削除する。
これを先頭行まで繰り返すと優先度の高い行のみ残る。
上記をコード化したコードが下記になります。
vba
1Public Sub Sample()
2 Dim dic As Object
3 Set dic = CreateObject("Scripting.Dictionary")
4 Dim tbl As Range
5 Set tbl = Worksheets(1).Cells(1, 1).CurrentRegion
6
7 Dim i As Long
8 For i = tbl.Rows.Count To 2 Step -1
9 Dim ky As String, pv As Long
10 ky = tbl.Cells(i, "C").Text
11 pv = Left(tbl.Cells(i, "D"), 1) * 10000 - tbl.Cells(i, "A")
12 If dic.Exists(ky) Then
13 If dic(ky) > pv Then
14 dic(ky) = pv
15 End If
16 Else
17 dic(ky) = pv
18 End If
19 Next
20
21 For i = tbl.Rows.Count To 2 Step -1
22 ky = tbl.Cells(i, "C").Text
23 pv = Left(tbl.Cells(i, "D"), 1) * 10000 - tbl.Cells(i, "A")
24 If dic(ky) <> pv Then
25 tbl.Rows(i).Delete
26 End If
27 Next
28End Sub
別案 式とフィルターを利用して手作業で
表範囲の右隣の空列の1行目に「比較値」と入力。
2行目に下記の式を設定する。
=LEFT(CB2,1)*10000-A2
フィルハンドルをダブルクリックすると最終行まで比較値が表示される
さらに右隣の列の1行目に「優先行」と入力。
2行目に下記の式を設定
`=MINIFS(CC$2:CC$6000,CA$2:CA$6000,CA2)=CC2
※CC は比較値の式を設定した列アドレス
フィルハンドルをダブルクリックすると最小比較値と一致する行はTRUE、不一致の行はFALSEとなる。
「優先行」列でフィルターをかけてFALSEの行を抽出する。
表示されている行を行削除する。
フィルターを解除する。
作業列2列を削除する。
以上。