- 최초 작성일: 2002-10-03
- 최종 수정일: 2026-09-30
- 조회수: 22 회
- 작성자: 권현욱 (엑셀러)
- 강의 제목: VBA로 VBA 코드 작성하기
들어가기 전에
오래 전 엑셀 파일로 진행하던 강의를 웹 글로 복원한 것이라, "버튼을 눌러보세요"처럼 엑셀에서 직접 조작하라는 표현이 남아 있을 수 있습니다. 결과는 본문의 그림이나 표로 확인하실 수 있으며, 현재와 맞지 않는 내용은 보완하되 전반적인 스타일은 당시의 갬성(?)을 유지했습니다.
When work is a pleasure, life is a joy! When work is a duty, life is slavery. 일하는 것이 즐거울 때, 인생은 기쁨 그 자체이다! 일하는 것이 의무로 다가올 때, 인생은 노예와 같다.
외부 자극에 반응하는 방식에 따라 우리의 삶은 자뭇 달라질 수도 있습니다.
VBA로 VBA 코드 작성하기
핵심 요약: 코드로 이벤트 프로시저 만들기
코드로 만든 컨트롤에 이벤트를 연결하려면 해당 시트의 코드 모듈에 이벤트 프로시저 문자열을 InsertLines로 삽입하면 됩니다.
- 1단계: Worksheets.Add로 시트를 만들고 OLEObjects.Add로 커맨드 버튼을 삽입합니다.
- 2단계: 삽입할 이벤트 프로시저 코드를 문자열 변수에 만들어 둡니다.
- 3단계: CodeModule의 마지막 줄 다음에 InsertLines로 코드를 삽입합니다.
Step 1: 어떤 질문이었을까요?
라벨과 텍스트박스, 체크박스, 커맨드버튼 등을 VBA 코드로 만들어 넣는 데까지는 성공했는데, 이 개체들의 이벤트는 어떻게 설정하느냐는 질문이었습니다. 디자인 모드에서 개체를 만들면 마우스 클릭 몇 번으로 Private Sub cmd_Cancel_Click() 같은 이벤트 프로시저가 자동으로 생기는데, 코드로 생성한 개체의 이름은 어떻게 알 수 있고 이벤트는 어떻게 설정하느냐는 것입니다.
Step 2: VBA로 VBA 코드 작성하기
개체의 이름은 개체를 삽입할 때마다 자동으로 부여가 됩니다. 개체의 이름은 해당 개체의 Name 속성을 사용하시면 되겠지요? 이번 시간에는 VBA 코드를 VBA로 작성하는 방법에 대해 설명드리겠습니다.
혹 매크로 바이러스 코드를 잘 살펴보신 분이 계시다면 짐작하시겠지만, 매크로 바이러스가 바로 질문하신 것과 같은 방식으로 코드를 복제하므로 우려가 되지 않는 것은 아닙니다만, Exceller의 홈을 찾아주시는 분들이라면 바이러스를 만들어 유포하는 색다른(?) 취미를 가진 분은 없으리라 믿고 힌트를 드립니다. ^^ 아래 버튼을 눌러 보세요.
새로운 시트가 생성됨과 동시에 그 시트의 Code Module에도 코드가 생성되었지요?
먼저, 위의 'Click Me!!!' 버튼에 연결된 코드입니다.
Private Sub CommandButton1_Click()
On Error Resume Next
AddCode
' 일반 모듈에 있는 AddCode 프로시저를 호출합니다.
If Err <> 0 Then
MsgBox "오류가 발생하였습니다", , "www.iExceller.com"
Else
MsgBox "상단의 버튼을 누르시면 원래 시트로 되돌아갑니다", , "www.iExceller.com"
End If
End Sub
이번에는 AddCode 프로시저의 내용을 보도록 하지요.
Sub AddCode()
Dim shtNewSheet As Worksheet
Dim btnButton As OLEObject
Dim strNewSheet As String
Dim strCode As String
Dim intLines As Integer
Set shtNewSheet = Worksheets.Add
strNewSheet = shtNewSheet.CodeName
Set btnButton = shtNewSheet.OLEObjects.Add("Forms.CommandButton.1")
' 워크시트를 한 장 추가하고 CommandButton 컨트롤을 삽입합니다.
With btnButton
.Left = 0
.Top = 0
.Width = 100
.Height = 25
.Object.Caption = "<<Back"
End With
' 커맨드 버튼의 위치와 크기, 캡션 속성을 설정하고...
strCode = strCode & "Private Sub CommandButton1_Click()" & vbCr
strCode = strCode & " On Error Resume Next" & vbCr & vbCr
strCode = strCode & " Sheets(""Preface"").Activate" & vbCr
strCode = strCode & " If Err <> 0 Then" & vbCr
strCode = strCode & " MsgBox ""오류가 발생하였습니다!""" & vbCr
strCode = strCode & " End If" & vbCr
strCode = strCode & "End Sub"
' Code Module에 삽입할 코드를 strCode라는 문자열 변수에 담아 둡니다.
With ThisWorkbook.VBProject.VBComponents(strNewSheet).CodeModule
intLines = .CountOfLines + 1
.InsertLines intLines, strCode
End With
' intLines 변수는 현재 모듈 내의 코드 라인 수를 파악한 다음 거기에 1을 더한 값을 가집니다.
' 이렇게 하는 이유는, 만약 사용자의 PC가 모듈이 삽입될 때마다 Option Explicit 이라는
' 구문을 추가하도록 세팅되어 있다면 오류가 발생하기 때문입니다.
' 그런 다음 InsertLines 메서드를 사용하여 모듈의 마지막 부분에 strCode, 즉 코드를 추가해
' 나가는 것입니다.
End Sub
핵심은 VBProject.VBComponents(...).CodeModule의 InsertLines 메서드입니다. 새 시트의 CodeName으로 해당 시트의 코드 모듈에 접근한 뒤, 그 안에 문자열로 만든 코드를 삽입하는 방식입니다. 개체의 이름은 삽입될 때 자동으로 부여되며 Name 속성으로 확인할 수 있으므로, 처음 만든 커맨드 버튼은 CommandButton1이라는 이름의 이벤트 프로시저를 가지게 됩니다.
삽입 위치를 CountOfLines에 1을 더한 값으로 지정한 이유는, 사용자 PC가 모듈 생성 시 Option Explicit 구문을 자동으로 추가하도록 설정되어 있더라도 오류가 나지 않게 하기 위해서입니다.
참고: VBA 코드로 VBA 코드를 다루려면 엑셀의 '보안 센터-매크로 설정'에서 'VBA 프로젝트 개체 모델에 안전하게 액세스할 수 있음' 옵션을 켜고, VB Editor에서 Microsoft Visual Basic for Applications Extensibility 라이브러리를 참조하는 것이 좋습니다.
다음 시간에 또...
정리 — 코드로 코드 작성하기 핵심
| 구분 | 사용한 코드 | 역할 |
|---|---|---|
| 컨트롤 삽입 | OLEObjects.Add("Forms.CommandButton.1") | 커맨드 버튼 생성 |
| 시트 모듈 참조 | VBProject.VBComponents(CodeName).CodeModule | 대상 코드 모듈 |
| 삽입 위치 | .CountOfLines + 1 | 모듈의 맨 끝 |
| 코드 삽입 | .InsertLines 줄번호, strCode | 이벤트 코드 작성 |
| 개체 이름 | 개체.Name | 자동 부여된 이름 확인 |
자주 묻는 질문 (FAQ)
Q1. 코드로 만든 개체의 이름은 어떻게 알 수 있나요?
개체를 삽입할 때 자동으로 부여되며 Name 속성으로 확인할 수 있습니다. 처음 삽입한 커맨드 버튼은 CommandButton1입니다.
Q2. 코드로 만든 컨트롤의 이벤트는 어떻게 설정하나요?
해당 시트나 유저폼의 코드 모듈에 이벤트 프로시저를 InsertLines로 삽입합니다.
Q3. 왜 CountOfLines에 1을 더하나요?
Option Explicit 등이 자동 추가되어 있어도 모듈의 끝에 코드를 붙이기 위해서입니다.
마치며
코드를 코드로 작성하는 방법은 강력한 만큼 신중하게 사용해야 합니다. 이벤트를 동적으로 연결해야 하는 개체 생성 작업에 응용해 보시기 바랍니다.