Excel VBA 반복문 – For Each, For Next, Do While, 중첩 반복문, 등
In this Article
VBA에서 효과적으로 작업하려면 반복문을 이해해야 합니다.
반복문을 사용하면 코드 블록을 정해진 횟수만큼 반복하거나 객체 집합의 각 객체에서 코드 블록을 반복할 수 있습니다.
먼저 반복문의 기능을 보여드리기 위해 몇 가지 예제를 보여드리겠습니다. 그런 다음 반복문에 대한 모든 것을 알려 드리겠습니다.
VBA 반복문 – 간단한 예제
For Each 반복문
For Each 문은 컬렉션(통합문서의 모든 워크시트, 범위 내의 모든 셀) 내의 모든 객체를 반복합니다.
통합 문서의 모든 워크시트 반복하기
이 코드는 통합 문서의 모든 워크시트를 반복하여 각 시트의 숨기기를 해제합니다:
Sub LoopThroughSheets()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Visible = True
Next
End Sub
범위 내 모든 셀 반복하기
이 코드는 셀 범위의 셀을 반복하여 셀 값이 음수, 양수 또는 0인지 테스트합니다:
Sub If_Loop()
Dim Cell as Range
For Each Cell In Range("A2:A6")
If Cell.Value > 0 Then
Cell.Offset(0, 1).Value = "양수"
ElseIf Cell.Value < 0 Then
Cell.Offset(0, 1).Value = "음수"
Else
Cell.Offset(0, 1).Value = "영"
End If
Next Cell
End Sub
For Next 반복문
“For” 반복문의 또 다른 유형은 For Next 반복문 입니다. For Next 루프를 사용하면 정수를 반복할 수 있습니다.
이 코드는 1부터 10까지의 정수를 반복하여 메시지 박스에 하나씩 표시합니다:
Sub ForLoop()
Dim i As Integer
For i = 1 To 10
MsgBox i
Next i
End Sub
Do While Loop
Do While 루프는 조건이 충족되는 동안 반복됩니다. 이 코드도 1부터 10까지의 정수를 반복하여 메시지 박스에 하나씩 표시합니다.
Sub DoWhileLoop()
Dim n As Integer
n = 1
Do While n < 11
MsgBox n
n = n + 1
Loop
End Sub
Do Until Loop
Do While 반복문과는 반대로 Do Until 반복문은 조건이 충족될 때까지 반복합니다. 이 코드는 앞의 두 예제와 동일한 작업을 수행합니다.
Sub DoUntilLoop()
Dim n As Integer
n = 1
Do Until n >= 10
MsgBox n
n = n + 1
Loop
End Sub
아래에서 자세히 설명하겠지만, 끝이 없는 반복을 만들지 않도록 Do While 또는 Do Until 반복문을 만들 때 각별히 주의해야 합니다.
VBA 루프 빌더
프리미엄 VBA Add-in: AutoMacro의 스크린샷입니다. 루프 빌더를 사용하면 여러 객체 또는 숫자를 반복하는 반복문을 빠르고 쉽게 만들 수 있습니다. 각 객체에 대해 작업을 수행하거나 특정 기준을 충족하는 객체만 선택할 수 있습니다.
이 애드인에는 다른 많은 코드 빌더, 광범위한 VBA 코드 라이브러리, 다양한 코딩 도구도 포함되어 있습니다. 모든 VBA 개발자에게 필수품입니다.
이제 다양한 유형의 반복문에 대해 자세히 살펴보겠습니다.
VBA For Next 반복문
For 반복문 구문
For Next 루프를 사용하면 코드 블록을 지정된 횟수만큼 반복할 수 있습니다. 구문은 다음과 같습니다:
[Dim Counter as Integer]
For Counter = Start to End [Step Value]
[Do Something]
Next [Counter]
Where the items in brackets are optional.
- [Dim Counter as Integer] – Counter 변수를 선언합니다. 모듈 상단에 Option Explicit 이 선언된 경우 필수입니다.
- Counter – 반복 횟수를 위해 사용되는 Integer 변수입니다.
- Start – 시작 값 (예. 1)
- End – 마지막 반복 값 (예. 10)
- [Step Value] – 이 매개변수를 통해 카운트를 1씩 증가시키는 대신 n씩 증가시키게 할 수 있습니다. 음수일 경우 역으로 감소시킬 수도 있습니다 (ex. Step -1)
- [Do Something] – 반복할 코드입니다
- Next [Counter] – For Next 문에서 한 회 반복에 대한 종료 문입니다. 카운터를 포함할 수도 있고 포함하지 않을 수도 있습니다. 하지만 카운터를 포함하면 코드를 더 쉽게 읽을 수 있으므로 포함할 것을 강력히 권장합니다.
아직 잘 이해가 안되신다면 다음 예제를 참고해 주세요:
10까지 세기
이 코드는 For-Next 반복문을 사용하여 10까지 카운트합니다:
Sub ForEach_CountTo10()
Dim n As Integer
For n = 1 To 10
MsgBox n
Next n
End Sub
For 문에서 증가값 설정하기
10까지 짝수만 세기
이 코드는 짝수만 계산하여 10까지 카운트합니다:
Sub ForEach_CountTo10_Even()
Dim n As Integer
For n = 2 To 10 Step 2
MsgBox n
Next n
End Sub
“Step 2″를 추가한 것을 알 수 있습니다. 이것은 For 반복문이 카운터를 2씩 “증가”하도록 지시합니다. 음수 단계 값을 사용하여 역으로 감소시킬 수도 있습니다:
For 문에서 감소값 설정하기
10부터 아래로 세기
이 코드는 10부터 카운트다운합니다:
Sub ForEach_Countdown_Inverse()
Dim n As Integer
For n = 10 To 1 Step -1
MsgBox n
Next n
MsgBox "Lift Off"
End Sub
셀이 비어 있으면 행 삭제하기
저는 음수로 Step을 설정하여 For 반복문을 사용하여 셀 범위를 반복하여 특정 기준을 충족하는 행을 삭제하는 데 가장 자주 사용했습니다. 위쪽 행에서 아래쪽 행으로 반복하여 행을 삭제하면 카운터가 의도하지 않게 설정되어 원하는 행을 삭제할 수 없습니다.
이 예에서는 빈 셀이 있는 행을 삭제합니다(맨 아래 행부터 시작):
Sub ForEach_DeleteRows_BlankCells()
Dim n As Integer
For n = 10 To 1 Step -1
If Range("a" & n).Value = "" Then
Range("a" & n).EntireRow.Delete
End If
Next n
End Sub
중첩된 For 반복문
하나의 For 반복문을 다른 For 반복문안에 “중첩”할 수 있습니다. 중첩된 For 루프를 사용하여 곱셈 테이블을 만들어 보겠습니다:
Sub Nested_ForEach_MultiplicationTable()
Dim row As Integer, col As Integer
For row = 1 To 9
For col = 1 To 9
Cells(row + 1, col + 1).Value = row * col
Next col
Next row
End Sub
Exit For
Exit For 문을 사용하면 For Next 반복문을 즉시 종료할 수 있습니다.
일반적으로 특정 조건이 충족되면 For Next 반복문을 종료하는 If 문과 함께 Exit For를 사용합니다.
예를 들어 For 루프를 사용하여 셀을 찾을 수 있습니다. 셀을 찾으면 루프를 종료하여 코드 속도를 높일 수 있습니다.
이 코드는 1행부터 1000행까지 반복하여 A열에서 ‘오류’를 찾습니다. 오류가 발견되면 해당 셀을 선택하고 발견된 오류에 대한 경고를 표시한 후 루프를 종료합니다:
Sub ExitFor_Loop()
Dim i As Integer
For i = 1 To 1000
If Range("A" & i).Value = "오류" Then
Range("A" & i).Select
MsgBox "오류가 발견되었습니다"
Exit For
End If
Next i
End Sub
중요: 중첩된 For 반복문의 경우 Exit For는 모든 활성 루프를 종료하는 것이 아니라 Exit For가 선언된 위치에 따라서 그 위치에 해당하는 For 반복문만 종료합니다.
Continue For
VBA에는 Visual Basic에 있는 “Continue” 명령이 없습니다. 대신 “Exit”를 사용해야 합니다.
VBA For Each 반복문
VBA For Each 반복문은 컬렉션의 모든 객체를 반복합니다:
- 범위의 모든 셀
- 통합 문서의 모든 워크시트
- 워크시트의 모든 도형
- 열려 있는 모든 통합 문서
중첩된 For Each 반복문에 대해 다음을 사용할 수도 있습니다:
- 모든 워크시트의 범위 내 모든 셀
- 모든 워크시트의 모든 도형
- 열려 있는 모든 통합 문서의 모든 시트
- 기타 등등
구문은 다음과 같습니다:
For Each Object in Collection
[Do Something]
Next [Object]
- Object – 범위, 워크시트, 통합 문서, 모양 등을 나타내는 변수(예: rng)
- Collection – 개체의 컬렉션(예: Range(“a1:a10”))
- [Do Something] – 각 개체에서 실행할 코드 블록
- Next [Object] – 종료 문입니다. [Object]는 선택 사항이지만 강력히 권장합니다.
범위의 셀에 대한 For Each 문
이 코드는 범위의 각 셀을 반복합니다:
Sub ForEachCell_inRange()
Dim cell As Range
For Each cell In Range("a1:a10")
cell.Value = cell.Offset(0,1).Value
Next cell
End Sub
통합문서의 워크시트에 대한 For Each 문
이 코드는 통합 문서의 모든 워크시트를 반복하여 각 시트의 보호를 해제합니다:
Sub ForEachSheet_inWorkbook()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Unprotect "password"
Next ws
End Sub
열린 통합문서에 대한 For Each 문
이 코드는 열려 있는 모든 통합 문서를 저장하고 닫습니다:
Sub ForEachWB_inWorkbooks()
Dim wb As Workbook
For Each wb In Workbooks
wb.Close SaveChanges:=True
Next wb
End Sub
워크시트의 도형에 대한 For Each 문
이 코드는 활성 시트의 모든 도형을 삭제합니다.
Sub ForEachShape()
Dim shp As Shape
For Each shp In ActiveSheet.Shapes
shp.Delete
Next shp
End Sub
통합문서의 모든 워크시트의 도형들에 대한 For Each 문
For Each 루프를 중첩할 수도 있습니다. 여기서는 활성 통합 문서의 모든 워크시트에 있는 모든 도형을 반복합니다:
Sub ForEachShape_inAllWorksheets()
Dim shp As Shape, ws As Worksheet
For Each ws In Worksheets
For Each shp In ws.Shapes
shp.Delete
Next shp
Next ws
End Sub
For Each – IF 문
앞서 언급했듯이 반복문 내에서 If 문을 사용하여 특정 조건이 충족되는 경우에만 작업을 수행할 수 있습니다.
이 코드는 범위의 모든 비어있는 셀이 해당하는 행을 숨깁니다:
Sub ForEachCell_inRange()
Dim cell As Range
For Each cell In Range("a1:a10")
If cell.Value = "" Then _
cell.EntireRow.Hidden = True
Next cell
End Sub
VBA Do While Loop
VBA Do While과 Do Until(다음 섹션 참조)은 매우 유사합니다. 조건이 충족되는 동안(또는 조건이 충족될 때까지) 루프를 반복합니다.
Do While 루프는 조건이 충족되는 동안 루프를 반복합니다.
다음은 Do While 구문입니다:
Do While Condition
[Do Something]
Loop
- Condition – 반복문을 수행하기 위한 조건입니다.
- [Do Something] – 반복할 코드블록입니다.
Do While 루프에서 Condition을 마지막 줄에 두고 반복문을 구성할 수도 있습니다:
Do
[Do Something]
Loop While Condition
각각의 구문이 어떻게 다르게 구성되는지 확인하려면 아래를 참고해 주세요.
Do While
아래 코드는 이전에 보여드렸던 Do While 루프입니다.
Sub DoWhileLoop()
Dim n As Integer
n = 1
Do While n < 11
MsgBox n
n = n + 1
Loop
End Sub
Loop While
Condition을 끝에 위치시키는 것을 제외한 나머지는 같은 방법으로 작성하여 실행해 보겠습니다.
Sub DoLoopWhile()
Dim n As Integer
n = 1
Do
MsgBox n
n = n + 1
Loop While n < 11
End Sub
VBA Do Until Loop
Do Until Loops는 특정 조건이 충족될 때까지 루프를 반복합니다. 구문은 기본적으로 Do While 루프와 동일합니다:
Do Until Condition
[Do Something]
Loop
Condition은 마찬가지로 루프의 시작 부분이나 끝부분에 지정할 수 있습니다:
Do
[Do Something]
Loop Until Condition
Do Until
do Until 루프는 이전 예제 실행 결과와 같이 10까지 카운트됩니다.
Sub DoUntilLoop()
Dim n As Integer
n = 1
Do Until n > 10
MsgBox n
n = n + 1
Loop
End Sub
Loop Until
Loop Until 루프는 10까지 카운트합니다:
Sub DoLoopUntil()
Dim n As Integer
n = 1
Do
MsgBox n
n = n + 1
Loop Until n > 10
End Sub
Do 루프 종료하기
Exit For를 사용하여 For 루프를 종료하는 것과 유사하게, Exit Do 명령을 사용하여 Do 루프를 즉시 종료할 수 있습니다.
Exit Do
다음은 Exit Do의 예입니다:
Sub ExitDo_Loop()
Dim i As Integer
i = 1
Do Until i > 1000
If Range("A" & i).Value = "오류" Then
Range("A" & i).Select
MsgBox "오류가 발견되었습니다"
Exit Do
End If
i = i + 1
Loop
End Sub
루프 종료 또는 중단
위에서 언급했듯이 Exit For 또는 Exit Do를 사용하여 루프를 종료할 수 있습니다:
Exit For
Exit Do
그러나 루프를 실행하기 전에 이러한 명령을 코드에 추가해야 합니다.
현재 실행 중인 루프를 ‘중단’하려는 경우 키보드에서 ESC 또는 CTRL + Pause Break를 눌러 종료를 시도해 볼 수 있습니다. 그러나 이 방법이 작동하지 않을 수도 있습니다. 작동하지 않는 경우 루프가 끝날 때까지 기다리거나 무한 루프의 경우 CTRL + ALT + Delete를 사용하여 Excel을 강제로 닫아야 합니다.
이런 이유 때문에 저는 Do 루프를 잘 사용하지 않습니다. 실수로 무한루프를 만들어 엑셀을 강제종료할 경우 작업하던 내용이 손실될 수 있습니다.
더 많은 반복문 예제
모든 행 반복하기
아래 코드는 한 열의 모든 행을 반복합니다:
Public Sub LoopThroughRows()
Dim cell As Range
For Each cell In Range("A:A")
If cell.value <> "" Then MsgBox cell.address & ": " & cell.Value
Next cell
End Sub
모든 열 반복하기
아래 코드는 한 행의 모든 열을 반복합니다:
Public Sub LoopThroughColumns()
Dim cell As Range
For Each cell In Range("1:1")
If cell.Value <> "" Then MsgBox cell.Address & ": " & cell.Value
Next cell
End Sub
폴더 내의 모든 파일들 반복하기
이 코드는 폴더의 모든 파일을 반복하여 목록을 생성합니다:
Sub LoopThroughFiles ()
Dim oFSO As Object
Dim oFolder As Object
Dim oFile As Object
Dim i As Integer
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder("C:\Demo)
i = 2
For Each oFile In oFolder.Files
Range("A" & i).value = oFile.Name
i = i + 1
Next oFile
End Sub
배열 반복하기
이 코드는 배열 ‘arrList’를 반복합니다:
For i = LBound(arrList) To UBound(arrList)
MsgBox arrList(i)
Next i
LBound 함수는 배열의 최소첨자를 가져오고 UBound 함수는 배열의 최대첨자를 가져옵니다.
Access VBA의 반복문
위의 예제 대부분은 Access VBA에서도 작동합니다. 한가지 다른점은 Access에서는 범위 개체가 아닌 레코드 집합 개체를 반복합니다.
Sub LoopThroughRecords()
On Error Resume Next
Dim dbs As Database
Dim rst As Recordset
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("tblClients", dbOpenDynaset)
With rst
.MoveLast
.MoveFirst
Do Until .EOF = True
MsgBox (rst.Fields("ClientName"))
.MoveNext
Loop
End With
rst.Close
Set rst = Nothing
Set dbs = Nothing
End Sub