For~Next 루프를 배울 때 흥미로운 것중 하나는 Step이다.
For counter [ As datatype ] = start To end [ Step step ]
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ counter ]
기본적으로 1씩 증가하면서 루프를 돌지만,
For index = 1 To 5
Debug.Print index & " "
Next
Debug.Print
' Output: 1 2 3 4 5
Step 을 사용하면 주어진 값만큼 건너 뛰면서 루프를 돌게 된다. Step 2라고 하면 카운터 변수가 2씩 증가하면서 루프가 실행되고 Step -1하면 역방향으로 1씩 감소하면서 루프를 돌게 된다.
For number = 2 To 0 Step -0.25
Debug.Print number & " "
Next
Debug.Print
' Output: 2 1.75 1.5 1.25 1 0.75 0.5 0.25 0
그런데, 평소 가지는 불만중 하나는 For Each구문이다. 이넘은 Step이라는 개념이 없다. 물론 개체를 루핑하는 것인데, 개체를 서수화하는 기준이 없으니 For Each가 할 수 없는 영역이다. 하지만 For Each 대신 Do Loop와 Offset 메서드를 가지고 이런 루프를 만들 수 있다. 다음은 A6~ A22 사이를 반복하면서 짝수 행의 주소만 찍는 것이다.
Set rngBegin = Sheet1.Range("A6")
Set rngEnd = Sheet1.Range("A22")
Set rng = rngBegin
Debug.Print rngBegin.Address
Debug.Print rngEnd.Address
step = 2
Do
Debug.Print rng.Address
Set rng = rng.Offset(step, 0)
If rng.Address = rngEnd.Address Then Exit Do
Loop
앞서의 주제와 별개의 얘기이지만 예제를 만들면서 If rng.Address = rngEnd.Address Then Exit Do을 처음에는 If rng Is rngEnd Then Exit Do으로 사용하였다. 런타임에러는 없지만 예상과는 달리 rngEnd, 즉 A22에서 종료되지 않는 문제가 있었다.
가만히 생각해보니 If rng Is rngEnd 는 문제가 있다. A22를 둘 다 가리키지만 사실 이 개체변수는 같은 것은 아니다. 개체변수를 선언할 때
Dim rng As Range
Dim rngEnd As Range
이 개체변수들의 메모리 주소는 스택에 있을 거구, 각각 다른 메모리 주소를 가질 것이다. 그러므로 A22라는 같은 값을 가질 수 있지만 , 주소는 달라서 같은 개체일 수는 없을 것이다.