-
Excel 매크로 (VBA) - 023. 클래스 모듈 (간단한 예제)Excel/Excel 매크로 2022. 11. 9. 21:14728x90
전체 목차
- 001. 특정 행을 복사하여 삽입하기
- 002. 선택하여 붙여 넣기 기능 정리
- 003. 변수/Assignment/Loop/비교
- 004. 데이터가 있는 셀의 범위 알아내기
- 005. 데이터 시트(쉘) 순회하기
- 006. 셀 병합 하기
- 007. 변수에 저장되어 있는 데이터 확인하기 (디버그 기능)
- 008. 정렬하기 (Sort)
- 009. 버튼 컨트롤 (Excel Form vs. ActiveX)
- 010. 콤보 상자 컨트롤 (Excel Form vs. ActiveX)
- 011. 확인란/옵션단추 컨트롤(Excel Form vs. ActiveX)
- 012. 스핀단추 컨트롤(스피너, Excel Form vs. ActiveX)
- 013. 자동필터(Auto Filter)
- 014. 함수(function) (전편)
- 015. 함수(function) (후편)
- 016. 중복 데이터 제거하기
- 017. 텍스트 나누기 (공백, 특수문자)
- 018. Vlookup으로 데이터 조회하기(주식 종목 코드 조회)
- 019. 런타임 에러 처리 (1)
- 020. 런타임 에러 처리 (2)
- 021. 인풋박스 (InputBox) 사용 방법- 022. 로또 번호 생성기를 만들어 보자
포스트 목차.
- 01. 클래스 모듈이란
- 02. 클래스 모듈에서 변수 선언하기
- 03. 클래스 모듈에서 함수 선언하기
- 04. 클래스 모듈에서 Sub 프로시저 선언하기
- 05. 정의한 클래스 모듈을 사용하기
01. 클래스 모듈이란VBA에서 클래스 모듈은 사용자가 정의한 객체라고 볼 수 있다. Range 객체처럼 Excel에서 제공하는 객체가 아닌 사용자가 필요에 따라 정의하는 객체(개체)를 의미한다.
클래스 모듈을 추가하는 방법은 다음과 같다.
(1) 개발 도구 > Visual Basic 실행
(2) 프로젝트 창에서 프로젝트나 클래스 모듈 선택
(3) 우클릭 후 삽입 > 클래스 모듈 선택
위의 절차에 따라 클래스 모듈을 추가할 수 있다. 추가 이후에는 다음과 같이 Class1이라는 클래스 모듈이 생성된다.
속성 부분의 (이름)을 변경하면 생성한 클래스 모듈의 이름을 변경할 수 있다. 원하는 이름으로 변경해보자.
클래스 모듈은 모듈처럼 소스코드를 입력할 수 있는 영역을 가지고 있다.
위의 그림에서 클래스 모듈을 선택하면 오른쪽 에디팅 영역에서 편집이 가능하다.
02. 클래스 모듈에서 변수 사용하기클래스 모듈에서 변수는 Public|Private 변수명 As 변수타입으로 선언할 수 있다.
이러한 변수들은 클래스 모듈의 멤버 변수라고 한다.
Public으로 선언할 경우 클래스 모듈을 사용하는 과정에서 사용자에게 노출된다.
Private으로 선언할 경우 클래스 모듈 내부에서만 해당 변수에 접근이 가능하고, 클래스 모듈 사용 시점에는 사용자에게 노출되지 않는다.
다음은 클래스 모듈의 이름을 "ClassExample"로 바꾼 상태에서 Public 한정자를 사용하여 7개의 Integer 형 변수를 선언하고 Private 한정자를 사용하여 1개의 Integer 형 배열을 선언한 예제이다.
이번에는 모듈에 있는 Sub 프로시저에서 클래스 모듈과 클래스 모듈에 선언되어 있는 멤버 변수들을 사용하는 방법에 대해 소개한다.
클래스 모듈을 모듈에 있는 Sub 프로시저에서 사용하기 위해서는 다음과 같은 선언이 필요하다.
Dim classEx As New ClassExample
- clssEx: 클래스 모듈에 접근하기 위한 변수명이다. (인스턴스 명이라고 보면된다.)
- New: Range객체처럼 엑셀에서 이미 만들어져 메모리 공간이 할당되어 있는 객체가 아니기 때문에 New 키워드를 사용하여 할당을 해줘야 한다.
- ClassExample: 클래스 모듈의 이름이다.
클래스 모듈에 대해 이해하기 힘들면, 우리가 새로운 타입의 변수를 선언하여 사용하는 거라고 일단 이해하고 넘어가도록 하자.
클래스 모듈의 변수명과 연산자(.)을 사용하면 멤버변수에 접근하는 것이 가능하다. (단, 멤버 변수 선언 시에 한정자를 Public으로 선언한 변수만 접근이 가능하다.)
위의 그림처럼 변수명 뒤에 .을 입력하면 접근할 수 있는 멤버들의 목록이 나온다.
"클래스 모듈의 변수명.멤버변수명"을 이용하여 변수에 값을 할당하거나, 변수 값을 이용하여 연산을 수행할 수 있다.
03. 클래스 모듈에서 함수 사용하기클래스 모듈에서 함수는 Public|Private Function 함수명(인자1 As 인자1 변수타입, .... ) As 함수의 반환값의 변수타입으로 선언할 수 있다.
Public|Private Function 함수명(인자1 As 인자1 변수타입, .... ) As 함수의 반환값의 변수타입
작성되는 위치만 다를 뿐 일반적인 함수의 선언과 형식은 일치한다. VBA의 함수에 대해 더 알고 싶으면 다음 링크를 참고하자.
https://eggdrop.tistory.com/28
https://eggdrop.tistory.com/29
이러한 함수들은 클래스 모듈의 멤버 함수라고 한다.
Public으로 선언할 경우 클래스 모듈을 사용하는 과정에서 사용자에게 노출된다.
Private으로 선언할 경우 클래스 모듈 내부에서만 해당 함수에 접근이 가능하고, 클래스 모듈 사용 시점에는 사용자에게 노출되지 않는다.
다음과 같은 두 함수가 선언되어 있을 때, 접근 가능성에 대해서 알아보자.
함수의 자세한 동작에 대해서는 05. 정의한 클래스 모듈을 사용하기에서 자세히 다루려고 한다 지금은 Private / Public에 대해서만 확인하기 바란다.
Private Function BonusNumberMatch(number1 As Integer, number2 As Integer, number3 As Integer, number4 As Integer, number5 As Integer, number6 As Integer) As Boolean Public Function CalcPrizeRank(number1 As Integer, number2 As Integer, number3 As Integer, number4 As Integer, number5 As Integer, number6 As Integer) As Integer 함수가 길지만, ClacPrizeRank 함수는 Public으로 선언되었기 때문에, 아래 그림처럼 클래스 모듈 외부에서 사용이 가능하다.
반면, BonusNubmerMatch 함수는 Private으로 선언되었기 때문에, 클래스 모듈 내부에서만 접근이 가능하다.
04. 클래스 모듈에서 Sub 프로시저 사용하기클래스 모듈에서 Sub 프로시저를 정의하는 것도 가능하다.
다음 예제를 통해 가볍게 접근해보자.
makeArrayWinningNumber 라는 이름의 Sub 프로시저를 Private 한정자를 이용하여 선언한 상태이다. 위 Sub 프로시저는winningNumbers라는 배열에 m_winningNumber1 ~ m_winnnigNumber6 까지의 숫자를 이력하는 코드가 작성되어 있다.
05. 정의한 클래스 모듈을 사용하기이제 구체적인 목표를 갖고 클래스 모듈을 정의해서 사용해보자.
본 포스트에서는 로또 당첨 번호와 보너스 번호를 멤버 변수로 하고, 6개의 숫자를 입력했을 때, 몇 등에 당첨되었는지를 반환하는 역할을 하는 클래스 모듈을 정의하려고 한다.
(1) 클래스 모듈 추가 / 변순 선언 / Sub 프로시저 선언
위의 그림처럼 ClassExample이라는 클래스 모듈을 추가했다.
또한 클래스 모듈에 다음 요소들을 추가했다.
- 당첨번호를 저장할 수 있는 6개의 Integer 변수
- 보너스 번호를 저장할 수 있는 1개의 Integer 변수
- 당첨번호를 내부적으로 저장할 크기 6의 Integer 배열
- 당첨번호를 Integer 배열에 넣어줄 Sub 프로시저
(2) 당첨번호와 입력된 숫자의 일치수를 확인하는 함수 선언
1234567891011121314151617181920212223242526Private Function NumOfMatch(number1 As Integer, number2 As Integer, number3 As Integer, number4 As Integer, number5 As Integer, number6 As Integer) As Integer'일치하는 숫자의 수를 저장하기 위한 변수Dim counter As Integercounter = 0'당첨번호를 배열에 삽입하는 Sub프로시저 호출Call makeArrayWinningNumber'입력받은 로또 번호를 배열로 변환Dim numbers(1 To 6) As Integernumbers(1) = number1numbers(2) = number2numbers(3) = number3numbers(4) = number4numbers(5) = number5numbers(6) = number6'입력받은 번호와 당첨번호를 순회하며 일치여부 확인, 일치 시에 counter 값 증가For i = 1 To 6For j = 1 To 6If numbers(i) = winningNumbers(j) Thencounter = counter + 1End IfNext jNext i'계산된 counter 값 반환NumOfMatch = counterEnd Functioncs 위 함수는 당첨번호와 입력된 6개의 숫자와의 일치 수를 반환하는 역할을 한다. 클래스 모듈 내부에서만 사용된다.
(3) 보너스 번호와 입력된 숫자의 일치수를 확인하는 함수 선언
123456789101112131415161718192021222324Private Function BonusNumberMatch(number1 As Integer, number2 As Integer, number3 As Integer, number4 As Integer, number5 As Integer, number6 As Integer) As Boolean'일치할 경우 True / 일치하지 않을 경우 False 반환'반환을 위한 변수 선언Dim retBool As BooleanretBool = False'입력받은 변수를 배열로 변경Dim numbers(1 To 6) As Integernumbers(1) = number1numbers(2) = number2numbers(3) = number3numbers(4) = number4numbers(5) = number5numbers(6) = number6'배열을 순회하며 멤버변수m_winningNumber_bonus 와 비교 작업 수행, 일치할 경우 반환값에 True를 입력하고 Loop를 탈출For i = 1 To 6If numbers(i) = m_winningNumber_bonus ThenretBool = TrueExit ForEnd IfNext i'반환값 설정BonusNumberMatch = retBoolEnd Functioncs 위 함수는 입력된 6개의 숫자와 보너스 숫자와의 일치여부를 확인한다. 크래스 모듈 내부에서만 사용된다.
(4) 로또 등수를 확인하는 함수 선언
1234567891011121314151617181920212223242526272829Public Function CalcPrizeRank(number1 As Integer, number2 As Integer, number3 As Integer, number4 As Integer, number5 As Integer, number6 As Integer) As IntegerDim myRank As IntegermyRank = 0Dim count As Integer'당첨번호와 일치 수 확인count = NumOfMatch(number1, number2, number3, number4, number5, number6)'6개 모두 일치 - 1등If count = 6 ThenmyRank = 1'5개 일치 & 보너스 번호 일치 - 2등ElseIf count = 5 And BonusNumberMatch(number1, number2, number3, number4, number5, number6) ThenmyRank = 2'5개 일치 - 3등ElseIf count = 5 ThenmyRank = 3'4개 일치 - 4등ElseIf count = 4 ThenmyRank = 4'3개 일치 - 5등ElseIf count = 3 ThenmyRank = 5End IfCalcPrizeRank = myRankEnd Functioncs 위 함수는 클래스 모듈 외부에서 접근이 가능한 함수이며, 인자로 숫자 6개를 입력받아, 로또 등수를 반환하는 역할을 한다. 낙첨인 경우 0이 반환되고, 당첨인 경우 해당 등수가 반환된다.
(5) 시트 설정
다음과 같이 시트에 당첨번호와 입력번호를 입력할 수 있는 영역을 만든다.
버튼을 하나 추가 후에 "계산"으로 텍스트를 변경한다.
위의 그림처럼 버튼에서 매크로 지정을 통해 버튼을 누르면 동작할 서브 프로시저를 추가한다.
(6) 모듈에 서브 프로시저 정의
다음과 같은 서브프로시저를 작성한다.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253Sub 당첨결과확인_Click()'데이터 유효성 검사 (숫자가 아닐 경우 바로 종료)For i = 2 To 7If Not IsNumeric(ActiveSheet.Cells(2, i)) ThenMsgBox ("숫자를 입력해주세요")Exit SubEnd IfIf Not IsNumeric(ActiveSheet.Cells(3, i)) ThenMsgBox ("숫자를 입력해주세요")Exit SubEnd IfNext iIf Not IsNumeric(ActiveSheet.Cells(2, 8)) ThenMsgBox ("숫자를 입력해주세요")Exit SubEnd If'클래스 모듈 선언Dim classEx As New ClassExample'클래스 모듈에 당첨번호 및 보너스 번호 입력classEx.m_winningNumber_1 = Int(ActiveSheet.Cells(2, 2))classEx.m_winningNumber_2 = Int(ActiveSheet.Cells(2, 3))classEx.m_winningNumber_3 = Int(ActiveSheet.Cells(2, 4))classEx.m_winningNumber_4 = Int(ActiveSheet.Cells(2, 5))classEx.m_winningNumber_5 = Int(ActiveSheet.Cells(2, 6))classEx.m_winningNumber_6 = Int(ActiveSheet.Cells(2, 7))classEx.m_winningNumber_bonus = Int(ActiveSheet.Cells(2, 8))'입력번호를 저장할 변수 선언 및 입력Dim myInteger1 As IntegerDim myInteger2 As IntegerDim myInteger3 As IntegerDim myInteger4 As IntegerDim myInteger5 As IntegerDim myInteger6 As IntegermyInteger1 = Int(ActiveSheet.Cells(3, 2))myInteger2 = Int(ActiveSheet.Cells(3, 3))myInteger3 = Int(ActiveSheet.Cells(3, 4))myInteger4 = Int(ActiveSheet.Cells(3, 5))myInteger5 = Int(ActiveSheet.Cells(3, 6))myInteger6 = Int(ActiveSheet.Cells(3, 7))'클래스 모듈의 ClacPrizeRank 함수를 통해 등수 계산myRank = classEx.CalcPrizeRank(myInteger1, myInteger2, myInteger3, myInteger4, myInteger5, myInteger6)' 반환값이 0인 경우 낙첨, 반환값이 0이 아닌 경우 등수를 메시지 박스에 출력If myRank = 0 ThenmyRankStr = "낙첨"ElsemyRankStr = myRank & "등"End IfMsgBox (myRankStr)End Subcs 클래스 모듈을 선언하고, 클래스 모듈의 멤버변수(당첨번호 + 보너스 숫자)를 채운 후에, 당첨 등수를 계산하는 ClacPrizeRank 함수를 호출한 결괄르 메시지 박스를 통해 보여주는 예제이다.
2등에 해당하는 숫자 입력후 계산 버튼을 클릭하면 2등이 계산되어 나오는 것을 확인할 수 있다.
728x90'Excel > Excel 매크로' 카테고리의 다른 글
엑셀 VBA 셀의 너비와 높이 가져오기 , 셀의 너비와 높이 변경하기 (1) 2023.05.22 VBA 중복데이터 합치기 (0) 2023.04.27 Excel 매크로 (VBA) - 022. 로또 번호 생성기를 만들어 보자 (0) 2022.11.05 Excel 매크로 (VBA) - 021. 인풋박스 (InputBox) 사용 방법 (0) 2022.09.14 Excel 매크로 (VBA) - 020. 런타임 에러 처리 (2) (0) 2022.09.13