エクセルVBA100本ノック。10本目:行の削除

この記事から得るもの

表から、不要な行の削除の仕方が分かる。


1 今回のお題

画像のように「受注」シートに今月の受注データがあります。
受注数が空欄かつ備考欄に「削除」または「不要」の文字が含まれている行を削除してください。
行の削除は行全体を削除してください。
サンプルでは5行目と10行目を削除



f:id:bimori466:20201106140845p:plain

excel-ubara.com

2 今回のお題の意図

削除の条件を定めて、行を削除できるようにすること。

3 回答

私の最初の回答

Sub ノック10本目()

Dim ws As Worksheet: Set ws = Worksheets("受注")
Dim Remarks As String


For k_Orders = ws.Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
    Remarks = ws.Cells(k_Orders, 4)
    
    If ws.Cells(k_Orders, 3) = "" Then
        If Remarks Like "*削除*" Or Remarks Like "*不要*" Then
            ws.Rows(k_Orders).Delete
        End If
    
    End If
Next

End Sub

行を削除するときは、ループで後ろから削除するのが基本です(STEP -1)。行を削除すると、行位置が1つ前にずれるからです。
例えば、Setp +1で実行して、行番号2を削除したとします。そうすると、行番号3が行番号2となります。ループ処理は次は3を処理するので、行番号2となったデータが処理されなくなってしまします。

しかし、どうやらこの1行1行判定する処理は、実行速度が遅いようです。そのため、AutoFilterで条件を絞って該当の行を削除する方が速いようです。

4 AutoFilterを使った削除

Autofilterを使った行の削除の例

Sub ノック10本目_2()

Worksheets("受注").AutoFilterMode = False

With Sheets("受注").Range("A1").CurrentRegion
    .AutoFilter field:=3, Criteria1:=""
    .AutoFilter field:=4, Criteria1:="*削除*", Operator:=xlOr, Criteria2:="*不要*"
    .Offset(1, 0).EntireRow.Delete
    .AutoFilter
End With

End Sub

まず、Autofilterがかかっていれば解除します。その後、フィルタをかけて、行を一気に削除します。
この方法の方が、処理が速いようです。今後はAutofilterの方で書いていこうかと思います。