Step없는 For Each와 그 대안

nØthing spec¡al by Jimsjoo·2024년 7월 25일
0

VBA

목록 보기
13/13

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라는 같은 값을 가질 수 있지만 , 주소는 달라서 같은 개체일 수는 없을 것이다.

profile
harmonized or torn between programming and finance

0개의 댓글