-
엑셀 매크로 (VBA) - 003. variable/assignment/branch/loop (변수/할당/비교/순환)Excel/Excel 매크로 2022. 8. 15. 17:56728x90
전체 목차
- 001. 특정 행을 복사하여 삽입하기
- 002. 선택하여 붙여 넣기 기능 정리
- 003. 변수/Assignment/Loop/비교
포스트 목차
- 01. VBA에서의 변수(variable)
- 02. VBA에서 할당(Assingment)
- 03. VBA에서 변수의 스코프(Scope)
- 04. 비교(Branch)
- 05. 순환(Loop)
본 포스트에서는 논리적인 관점에서 프로그래밍의 3대 기능인 Assignment / Loop / Branch 가 VBA에서 어떤 문법으로 구성되는지를 정리해보려 한다. 해당 기능을 다루기 전에 변수에 대해서 먼저 가볍게 다루도록 하겠다.
01. VBA에서의 변수
변수는 프로그램이의 중간 결과물 또는 최종 결과물이 저장되는 공간이라고 생각하면 된다. 선언을 통해 VBA 컴파일러에게 이 변수의 이름, 형식등을 알려주고 이후에는 변수 이름으로 접근할 수 있다.
변수 선언을 위해서는 Dim 이라는 키워드를 이용해야 한다.
예) Dim [변수명] as [변수타입]
변수명을 작성할 때는 다음 사항을 주의해야 한다.
- 예약어(Next, Loop 등등) 사용 금지
- 일부 특수 문자 사용 금지($ * ! % & # . ,)
- 공백 사용금지
- 대소문자 구분없음
- 첫문자는 알파벳만 허용, 숫자와 _는 첫문자 외에는 사용가능
- 변수명은 255 문자를 넘을 수 없음
변수타입은 크게 "숫자"와 "숫자외" 타입으로 분류된다.
- 숫자타입: Byte(0~255) , Integer(-32768~32768), Long(-2,147,483 ~ 2,147,483,648), Single/Double(부동소수점), Currency(통화), Decimal(십진수)
- 숫자외 타입: String(문자열), Boolean(참/거짓), Object(객체), Date(날짜), Variant(가변데이터)
숫자 타입을 사용할 때는 값의 저장 범위를 주의해서 살펴야한다. 담을 수 있는 값보다 큰 값을 할당할 경우 overflow 에러가 발생한다.
02. VBA에서 할당(Assingment)
프로그래머가 선언한 변수 또는 시스템 변수에 특정 값을 할당할 수 있다.
VBA에서는 "=" 연산자를 이용하여 "할당"을 할 수 있다.
아래와 같은 형태로 할당 할 수 있다.
변수명 = 할당할 값
다음과 같은 예제를 실행해보자.
12345678910111213Sub TestSub4()Dim testVal As IntegerDim testVal2 As StringtestVal = 2testVal2 = "테스트"MsgBox (testVal)MsgBox (testVal2)End Subcs 3~4: Integer 형의 testVal 이란 변수와 String 형의 testVal2란 변수를 선언했다.
7~8: 각각의 변수에 형태에 맞는 값을 할당한다.
10~11: 각각의 변수에 할당되어 있는 값을 메시지 박스를 통해 출력한다.
매크로 TestSub4를 실행한다.
다음과 같은 메시지 박스가 두번 출력되어 의도하였던 값인 2와 테스트가 찍히는 것을 확인할 수 있다.
할당 시에 주의해야 할 것은 변수의 타입에 맞는 값을 할당해야된다는 것이다. 다음 예제는 위의 예제에서 Integer 변수에 텍스트를 삽입하고 String 변수에 숫자를 삽입한 Sub 프로시저이다.
12345678910111213Sub TestSub3()Dim testVal As IntegerDim testVal2 As StringtestVal = "테스트"testVal2 = 2MsgBox (testVal)MsgBox (testVal2)End Subcs 실행하면 다음과 같은 에러가 발생하는 것을 알 수 있다.
03. VBA에서 변수의 스코프(Scope)
변수 할당과 관련되어 있는 키워드는 Dim, Public, Private이 있다.
Public [변수명] as [변수형식]
Private [ 변수명] as [변수형식]
변수를 선언한 후에, 우리는 그 변수에 접근하여 값을 가져오거나, 변수에 값을 할당 할 수 있다. 변수에 접근하는 것은 소스코드의 모든 부분에서 가능한 것이 아니고, 변수의 스코프내에서만 접근이 가능하다.
예를 들어 sub 프로시저 내부에서 선언된 변수는 sub 프로시저 내부에서만 접근이 가능하다.
변수가 선언된 위치 및 선언에 사용된 키워드에 따라 변수의 스코프가 결정된다.
변수의 스코프를 테스트하기 위해 하나의 엑셀 파일에 모듈2개를 삽입한 후에, 다음과 같은 함수 3개를 정의해보자.
- Module1
123456789101112131415161718192021222324Private endRowPrivate As LongPublic endRowPublic As LongDim endRowScope1 As LongSub TestSub1()Dim endRow As LongendRow = 32endRowScope1 = endRowendRowPublic = endRowendRowPrivate = endRowMsgBox (endRow)End SubSub TestSub2()MsgBox ("local:" & endRow)MsgBox ("dim:" & endRowScope1)MsgBox ("public:" & endRowPublic)MsgBox ("private:" & endRowPrivate)End Subcs 1: Private 키워드를 이용하여 endRowPrivate 이란 Long 타입의 변수를 선언한다.
2: Public 키워드를 이용하여 endRowPublic 이란 Long 타입의 변수를 선언한다.
3: Dim 키워드를 이용하여 endRowScope1 이란 Long 타입의 변수를 선언한다.
5: TestSub1이란 Sub 프로시저를 선언한다.
7: endRow란 Long 타입의 변수를 선언한다.
8: endRow 변수에 값 32를 할당한다.
9~11: endRowPrivate , endRowPublic, endRowScope1 변수에 각각 endRow에 있는 값(32)을 할당한다.
13: 메시지 박스에 endRow에 저장된 값을 출력한다.
17: TestSub2란 Sub 프로시저를 선언한다.
19~22: endRow, endRowPrivate , endRowPublic, endRowScope1에 저장되어 있는 값을 각각 출력한다.
- Module2
12345678Sub TestSub5()MsgBox ("local:" & endRow)MsgBox ("dim:" & endRowScope1)MsgBox ("public:" & endRowPublic)MsgBox ("private:" & endRowPrivate)End Subcs 1: TestSub5 라는 Sub 프로시저를 선언한다.
3~6: endRow, endRowPrivate , endRowPublic, endRowScope1에 저장되어 있는 값을 각각 출력한다.
Moudle1에 정의되어있는 TestSub1을 실행한 결과는 다음과 같다.
Sub 프로시저 TestSub1 은 endRow, endRowScope1, endRowPublic, endRowPrivate 라는 변수에 각각 32를 할당한 후, endRow의 값을 메시지 박스에 출력하며 종료된다.
TestSub1을 실행 한 후 Moudle1에 정의되어있는 TestSub2를 실행한 결과는 다음과 같다.
Sub 프로시저 TestSub2는 endRow, endRowScope1, endRowPublic, endRowPrivate 라는 변수에 저장되어 있는 값을 각각 출력한다. 변수에 저장된 값 바로 앞에 특정 문자를 추가하여 출력한다. endRow에는 "local:", endRowScope1에는 "dim:", endRowPublic에는 "public:", endRowPrivate에는 "private:"이 추가된다.
- TestSub1에서 선언된 endRow를 출력한 결과에는 아무런 값이 출력되지 않았다. 즉 endRow 변수는 TestSub1 내에서만 접근할 수 있다는 것을 뜻한다.
- Sub 프로시저 밖에서 선언된 endRowScope1, endRowPublic, endRowPrivate에 대해서는 32라는 값이 할당된 것을 확인할 수 있다. Sub 프로시저 밖에서 선언된 변수는 같은 모듈안에 있는 Sub 프로시저 안에서 접근이 가능하다는 것을 알 수 있다.
Module2에 정의되어 있는 TestSub5를 실행한 결과는 다음과 같다.
Sub 프로시저 TestSub5도 TestSub2와 같은 동작을 하게 정의되어 있지만 출력된 값에는 차이가 있다. Sub 프로시저 밖에서 선언된 변수인 endRowScope1과 endRowPrivate에 있는 값에는 TestSub5에서 접근이 불가능하다는 것을 의미한다. 그러나 public 키워드를 이용하여 선언된 endRowPublic에는 접근이 가능하다는 것을 알 수 있다. Sub 프로시저 밖에서 Public 키워드로 정의되어 있는 변수의 경우, 다른 Module에서도 접근이 가능하다는 것을 알 수 있다. 반면 Sub 프로시저 밖에서 Private이나 Dim 키워드로 선언된 변수는 다른 Module에서 접근이 불가능하다는 것을 알 수 있다.
04. 비교(Branch)
프로그램은 대부분의 작업을 할 때 비교를 수행한다.
키워드 If, Then, Else, Elseif, End If를 이용하여 비교를 수행 할 수 있다.
다음과 같은 형태로 사용할 수 있으며, ElseIf의 경우 여러 개를 사용하는 것이 가능하다. 상위에 있는 조건을 만족할 경우 해당 실행문만 실행이되며, 다른 비교구문과 실행문들은 실행되지 않는다. 또한 실행문 자리에 또다른 If 구분을 추가하는 것이 가능하다.
If나 elseIf 다음에 오는 조건은 참 또는 거짓 형태로 해독 할 수 있는 변수나 표현식이어야 한다.
If 조건_if Then
실행문_if
End IfIf 조건_if Then
실행문_if
Else
실행문_else
End IfIf 조건_if Then
실행문_if
ElseIf 조건_elseif_1
실행문_elseif_1
End IfIf 조건_if Then
실행문_if
ElseIf
실행문_elseif_1
Else
실행문_else
End If간단한 If 문을 구현한 다음 예제를 실행해보자.
123456789101112131415161718192021222324252627Sub TestIf()Dim Number As IntegerDim Digits As IntegerDim MyString As StringNumber = 53If Number < 10 ThenDigits = 1ElseIf Numer < 100 ThenDigits = 2ElseDigits = 3End IfIf Digits = 1 ThenMyString = "One"ElseIf Digits = 2 ThenMyString = "Two"ElseMyString = "More than two"End IfMsgBox (MyString)End Subcs 53이 10보다 크고 100보다 작기 때문에 Digits 값이 2가 되고 Digits 값이 2가되면 MyString 값은 Two가 된다.
결과는 다음과 같다.
05. 순환(Loop)
프로그램은 할당, 비교, 순환의 연속이라고 볼 수 있다. 우리는 특정 조건을 만족시키는 동안 특정 코드를 계속해서 반복해야되는 일들에 노출되어 있다. 예를 들어, 엑셀 시트의 A열에 있는 모든 데이터를 한번씩 읽어야될 일이 있다고 가정하자. 누군가는 A열에 있는 데이터 수만큼 데이터를 읽는 코드를 추가할 수도 있지만, 순환문을 이용한다면 해당 작업을 잛은 몇줄의 코드로 대체할 수 있을 것이다.
- For ... Next 문
For counter = start To end [Step step]
[반복 구문] [Exit For]
Next [counter]
- For Each..Next 문
For Each element In group
[반복 구문][Exit For]
Next [element]
- While...Wend 문
While condition
[반복구문]
Wend
- Do...Loop 문
Do While 또는 Until 조건
[반복 구문] [Exit Do]
LoopDo
[반복 구문] [Exit Do]
Loop While 또는 Until 조건*[] 안에 있는 내용은 생략가능
다음은 For..Next 문, While...Wend 문, Do .. Loop 문을 사용하여 1에서 10까지의 숫자의 합을 출력하는 매크로의 예제이다. (For Each...Next 문은 다음에 다루기로 하자)
123456789101112131415161718192021222324252627Sub TestLoop()'변수 선언Dim total As IntegerDim tmp As Integertotal = 0'For..Next 문For a = 1 To 10total = total + aNext aMsgBox ("For: " & total)'While..Wend 문total = 0tmp = 1While tmp <= 10total = total + tmptmp = tmp + 1WendMsgBox ("While: " & total)'Do.. Loop 문total = 0tmp = 1Do While tmp <= 10total = total + tmptmp = tmp + 1LoopMsgBox ("Do: " & total)End Subcs 실행 결과는 다음과 같다.
지금까지 프로그램의 3요소라고 볼 수 있는 할당, 비교, 루프에 대해 다뤘다. 다음 포스트에서는 For Each ... Next 구문과 해당 내용을 다루기 위해 필요한 개념에 대해 다룰 예정이다.
728x90'Excel > Excel 매크로' 카테고리의 다른 글
Excel 매크로 (VBA) - 006. 셀 병합 하기 (0) 2022.08.18 Excel 매크로 (VBA) - 005. 시트에 있는 데이터(셀) 순회하기 (0) 2022.08.17 Excel 매크로 (VBA) - 004. 데이터가 있는 셀의 범위 알아내기 (0) 2022.08.16 엑셀 매크로 (VBA) - 002. 선택하여 붙여 넣기 기능 정리 (0) 2022.08.13 엑셀 매크로 (VBA) - 001. 특정 행을 복사하여 삽입하기 (1) 2022.08.12