엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 주의할 점과 올바른 삭제 방법


엑셀에서 VBA로 매크로 프로그램을 작성할 때 반복문을 많이 사용하게 됩니다.

대표적인 반복문으로 [For ~ Next]문과 [For Each ~ Next]문이 있습니다.

이번 글에서는 엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 주의할 점과 올바른 삭제 방법에 대한 내용입니다.

For문 또는 For Each문을 사용하여 행을 삭제하는 일반적인 예제 소스를 보면서 잘못 된 이유와 올바르게 삭제하는 방법을 알아 보겠습니다.

예제로 사용할 엑셀 화면입니다. 노란색으로 표시된 ‘사과’가 들어 있는 행(Row)를 모두 삭제하는 예제 입니다.

엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 주의할 점과 올바른 삭제 방법

엑셀 VBA에서 For Each 문을 사용해서 조건에 해당하는 Row 삭제하는 방법 (잘못된 방 예시)

아래 VBA 소스는 For Each ~ Next 문을 사용하여 셀 값이 ‘사과’인 행을 삭제하는 구문 입니다.

Sub 반복문_행삭제1()
‘ For Each문을 사용하여 행을 삭제할 때 문제점
 
    Dim Cell As Range
 
    ‘Cell 값이 ‘사과’인 행(Row) 삭제
 
    For Each Cell In ActiveSheet.UsedRange.Columns(1).Cells
        If Cell.Value = “사과” Then Cell.EntireRow.Delete
    Next Cell
 
    MsgBox “행을 삭제하였습니다!”
 
End Sub
 

▼ 아래 화면은 위의 VBA 프로그램을 실행했을 때 결과 입니다.

화면에서 보면 알겠지만 5행의 ‘사과’가 삭제되지 않고 남아 있는 것을 볼 수 있습니다.

엑셀 VBA - 반복문(Loop)을 사용하여 행을 삭제할 때 주의할 점과 올바른 삭제 방법 - 잘못된 예

For문이든 For Each문이든 Row를 반복한다고 했을 때 Next문을 만나게 되면 Row의 위치가 1 증가하게 됩니다. (For문의 Step이 지정된 경우 지정된 수만큼 증가 또는 감소 합니다.)

따라서 3행을 삭제하게되면 4행이 3행의 위치로 오게 되게 Next를 하게되면 체크할 행이 4행 되므로 기존 4행에서 3행으로 이동된 행은 체크에서 제외되게 됩니다.

그래서 위와 같은 오류가 발생하게 됩니다.

반복문을 사용하여 행을 삭제할 때 아래 두 가지 방법을 사용하여 처리하면 오류 없이 올바르게 행을 삭제할 수 있습니다.

엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 마지막 행부터 삭제하며 올라오는 방법

앞의 For Each문의 문제가 행을 삭제하면 다음 행이 한칸 앞으로 올라오는 문제 때문에 생긴 오류였습니다.

이러한 오류를 방지하기 위해 행의 맨 마지막부터 첫 행으로 반복문을 역으로 수행하는 것입니다.
(참고로 행의 마지막 위치를 찾는 방법은 엑셀 VBA에서 워크시트의 마지막 셀 위치(행, 열, 셀 주소)를 가져오는 방법 글을 참고하시면 됩니다.)

아래 VBA 소스는 행의 마지막에서 1행까지 -1 Step으로 처리하는 예제 입니다.

Sub 반복문_행삭제2()
‘ For문을 사용하여 행의 끝에서부터 앞으로 삭제하는 방법
 
    Dim pos As Long
 
    ‘Cell 값이 ‘사과’인 행(Row) 삭제
 
    For pos = ActiveSheet.UsedRange.Rows.Count To 1 Step 1
        If ActiveSheet.UsedRange.Cells(pos, 1).Value = “사과” Then
            ActiveSheet.UsedRange.Rows(pos).EntireRow.Delete
        End If
    Next pos
 
    MsgBox “행을 삭제하였습니다!”
 
End Sub
 

▼ 아래 화면은 위의 VBA 프로그램을 실행했을 때 결과 화면입니다.

‘사과’가 포함된 여러 행이 모두 삭제된 것을 확인할 수 있습니다.

엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 마지막 행부터 삭제하며 올라오는 방법

엑셀 VBA에서 반복문을 사용하여 행을 삭제할 때 삭제 후 다음 위치를 한 칸 앞으로 조정

처음의 For Each문과 동일한 방법으로 처음부터 차례대로 행을 체크해서 삭제를 하는 방식은 똑같지만 삭제했을 때 행의 위치를 한 칸 앞으로 임의로 조정하는 구문이 하나 더 들어 있습니다.

따라서 3행을 삭제했다고 했을 때 현재 위치를 2행으로 조정하고, Next문을 만나면 다시 3행이 되므로 결과적으로 3행을 다시 반복해서 체크하게 되는 것입니다.

Sub 반복문_행삭제3()
‘ For문을 사용하여 행이 삭제된 경우 행의 위치를 한칸 앞으로 조정
 
    Dim pos As Long
 
    ‘Cell 값이 ‘사과’인 행(Row) 삭제
 
    For pos = 1 To ActiveSheet.UsedRange.Rows.Count
        If ActiveSheet.UsedRange.Cells(pos, 1).Value = “사과” Then
            ActiveSheet.UsedRange.Rows(pos).EntireRow.Delete
            pos = pos  1
        End If
    Next pos
 
    MsgBox “행을 삭제하였습니다!”
 
End Sub
 

당연히 실행 결과는 행의 마지막부터 역으로 반복 처리했을 때의 결과와 동일한 결과로 얻을 수 있습니다.





이 글이 도움이 되었기를 바랍니다. ^-^


답글 남기기