VBA 실행속도는 느린 데, 그 이유에는 몇 가지가 있다. 우선 인터프리터형 언어이기 때문에 소스코드를 한 줄 한 줄 읽어서 해석되어 실행되기 때문이다. 두 번째는 엑셀의 워크시트에 쓰는 경우 더욱 더 느려진다. 그래서 VBA가 실행되는 동안 워크시트 렌더링을 잠시 막고, 수식 재계산을 막고, 이벤트 프로시저 작동을 잠시 중지시켜놓기도 한다. 그러나 이런 조치에도 불구하고 VBA의 실행속도는 만족스럽지 못하다.
이번 포스팅에서 VBA의 느린 속도를 극복하기 위한 방법중 하나를 소개하고자 한다. 우리의 가장 흔한 작업중 하나는 For 또는 Do 루프안에서 워크시트에 쓰는 무언가를 기록하는 것이다. 다음은 루프를 사용하지 않고 여러 개의 데이터를 여러 셀에 기록하는 코드 예다.
Dim myStr As String
myStr = "a string from vba"
With Sheet1.Range("D1")
.Offset(0, 1).Resize(1, 2) = "Single Value"
.Offset(1, 1).Resize(1, 2) = Array("Price", "Delta")
.Offset(2, 1).Resize(3, 2) = [{"Zip", "22150";"City", "Springfield"; "State", "VA"}]
.Offset(5, 1).Resize(1, 3) = Array([Today()], [Now()], myStr)
End With
위의 코드에서 D1셀을 기준으로 여러 형태의 데이터를 워크시트에 기록한다.
With Sheet1.Range("D1")
D1셀에서 컬럼 하나 떨어진 E1셀에 단일 값을 출력한다.
.Offset(0, 1).Resize(1, 2) = "Single Value"
D1셀에서 한 행, 한 컬럼 떨어진 셀(Offset(1, 1))에서 두 개의 셀영역을 잡고(Resize(1, 2)) 거기에 Array함수로 만든 배열을 출력한다.
.Offset(1, 1).Resize(1, 2) = Array("Price", "Delta")
이번에도 역시 D1셀에서 두 행, 한 컬럼 떨어진 셀을 기준으로 3x2 크기의 셀 영역에 엑셀의 배열 리터럴({})을 출력한다. {}은 엑셀에서 배열을 입력하는 리터럴인데, 이 리터럴에서 세미콜론(;)은 행을 구분하는 identifier다. {}를 둘러싼 []은 VBA에서 셀 영역을 가리키는 identifier다. 아마도 표를 출력하는 데, 가장 도움이 될 예제다.
.Offset(2, 1).Resize(3, 2) = [{"Zip", "22150";"City", "Springfield"; "State", "VA"}]
마지막은 D1셀에서 5행 1열 떨어진 셀을 기준으로 1x3 크기의 셀 영역에 배열을 출력한다. 이번 예가 앞서 배열을 출력하는 예와 다른 점은 배열에 VBA 함수(Today, Now함수)를 담았다는 점이다.
.Offset(5, 1).Resize(1, 3) = Array([Today()], [Now()], myStr)
End With
VBA는 다른 프로그래밍 언어에 비해 그 기능이 상당히 떨어진다. 그러나 우리는 여러 가지 스킬을 이용하여 그 단점을 보완할 수 있다.