엑셀 VBA에서 변수의 범위(scope)와 수명(lifetime)을 정확히 이해하면 모듈 간 데이터 교환, 메모리 관리, 디버깅 효율이 획기적으로 향상된다. 본 글은 Public과 Private을 중심으로 각 선언 키워드가 실제 코드에서 어떻게 작동하는지를 다룬다. 실무 예제와 표를 통해 독자가 즉시 현장 적용할 수 있는 지식을 제공한다.
변수 범위와 수명의 개념
범위(scope)란 변수를 참조할 수 있는 코드 영역이며, 수명(lifetime)은 변수가 메모리에 존재하는 기간이다. VBA는 모듈 구조 언어이므로 프로시저 수준, 모듈 수준, 프로젝트(전역) 수준으로 구분한다.
프로시저 수준(Local)
Dim
또는Static
으로 선언한다.- 변수는 해당 프로시저 내부에서만 참조 가능하다.
Dim
→ 프로시저 종료 시 메모리 소멸Static
→ 프로시저 종료 후에도 값 유지
모듈 수준(Private Module Variable)
Private
로 모듈의 시작 부분(Option 문 바로 아래)에서 선언한다.- 동일 모듈의 모든 프로시저에서 공유된다.
- 워크북 열려 있는 동안 메모리에 유지된다.
프로젝트 수준(Global / Public)
Public
으로 표준 모듈(.bas) 상단에 선언한다.- 모든 모듈과 폼, 클래스에서 참조 가능하다.
- 워크북이 닫힐 때까지 메모리에 남는다.
Private
이 기본이다. Public 멤버를 노출할 때는 프로퍼티를 통해 캡슐화하는 편이 좋다.선언 키워드 비교
키워드 | 선언 위치 | 접근 가능 영역 | 수명 | 주요 용도 |
---|---|---|---|---|
Dim | 프로시저 내부 / 모듈 상단 | 로컬 / 모듈 | 프로시저 실행 중 / 워크북 | 일반적인 지역 변수 |
Static | 프로시저 내부 | 로컬 | 워크북 | 함수 누적 계산, 카운터 |
Private | 모듈 상단 | 모듈 | 워크북 | 모듈 내부 공유, 캡슐화 |
Public | 표준 모듈 상단 | 프로젝트 전체 | 워크북 | 전역 상수, 공용 캐시 |
Public, Private 사용 실무 패턴
1) 전역 상수와 설정 값
'------ ModGlobals.bas ------
Option Explicit
Public Const APP_NAME As String = "WayFix Compliance Tool"
Public gDebugMode As Boolean
프로젝트 전체에서 참조하여 값 일관성을 유지한다.
2) 데이터 캐싱 예시
Option Explicit
Private dictCache As Object
Public Function GetChemicalName(casNo As String) As String
If dictCache Is Nothing Then
Set dictCache = CreateObject("Scripting.Dictionary")
End If
If Not dictCache.Exists(casNo) Then
dictCache(casNo) = QueryDatabaseForName(casNo)
End If
GetChemicalName = dictCache(casNo)
End Function
dictCache
는 모듈 전체에서 공유되며, 반복 조회 시 성능이 향상된다.
3) 클래스 캡슐화
'------ CConfig.cls ------
Option Explicit
Private pPath As String
Public Property Get FilePath() As String
FilePath = pPath
End Property
Public Property Let FilePath(val As String)
pPath = val
End Property
외부에서는 FilePath
프로퍼티를 통해서만 접근할 수 있으며 pPath
는 숨겨진다.
모듈 유형에 따른 범위 주의점
표준 모듈(.bas)
여기에 선언된 Public
변수는 프로젝트 전역에 즉시 노출된다. 대규모 프로젝트에서는 네임스페이스 충돌을 방지하기 위해 접두어(prefix) 전략을 권장한다.
워크시트/워크북 모듈
Public
으로 선언해도 해당 객체의 CodeName
을 통해서만 접근 가능하다. 예를 들어 Sheet1.myVar
형태로 호출한다.
UserForm 모듈
폼이 언로드(Unload)될 때 변수도 소멸된다. 상태 유지가 필요하다면 Public
전역 캐시에 저장한다.
메모리 관리와 디버깅 전략
- 불필요한 Public 변수 최소화 → 전역 상태 남발은 Side Effect 위험을 증가시킨다.
- Option Explicit 사용 → 모든 변수 명시 선언을 강제하여 오타 방지
- 모듈 분리 → 기능별 모듈을 분리하고, 범위를 가장 좁게 유지한다.
- Watcher, Locals 윈도우 활용 → 디버깅 시 변수 변경 추적에 유리하다.
Public/Private 혼용 시 베스트 프랙티스
- 초기 설계 단계에서 전역 변수 목록을 정의한다.
- 값 변경이 빈번한 변수는 전역 대신 함수 반환 값이나 파라미터로 전달한다.
- 도메인 객체(클래스)를 이용해 상태를 객체 내부에 숨긴다.
- 외부 시스템(API·DB) 연결 정보는
Public Const
로 읽기 전용 선언하여 보안을 강화한다. - 많은 모듈에서 동일 상수를 공유할 때는 Enum을 사용해 가독성을 높인다.
예제 프로젝트: 다중 모듈 간 데이터 교환
다음 예제는 화관법 보고용 CSV를 생성하는 워크북에서, 여러 모듈이 Public Type
구조체를 공유하여 데이터를 교환하는 시나리오이다.
'------ ModTypes.bas ------
Option Explicit
Public Type ChemInfo
CasNo As String
NameKo As String
Mass As Double
End Type
'------ ModLoader.bas ------
Option Explicit
Public collChem As Collection
Sub LoadData()
Dim ws As Worksheet: Set ws = Worksheets("Raw")
Dim i As Long, ci As ChemInfo
Set collChem = New Collection
For i = 2 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
ci.CasNo = ws.Cells(i, 1).Value
ci.NameKo = ws.Cells(i, 2).Value
ci.Mass = ws.Cells(i, 3).Value
collChem.Add ci
Next i
End Sub
'------ ModReport.bas ------
Option Explicit
Sub ExportCSV()
Dim fso As Object, ts As Object, ci As ChemInfo
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.CreateTextFile(ThisWorkbook.Path & "\report.csv", True, True)
For Each ci In collChem
ts.WriteLine ci.CasNo & "," & ci.NameKo & "," & Format(ci.Mass, "0.00")
Next ci
ts.Close
End Sub
위 구조는 데이터 적재(LoadData)와 출력(ExportCSV)을 모듈별로 분리했다. 전역 변수 collChem
만 공유하므로 유지보수가 용이하다.
FAQ
Q1. Dim을 모듈 상단에 선언하면 Public과 같은가?
아니다. 모듈 상단에서 Dim
으로 선언하면 해당 모듈 내부에서만 접근 가능하다. 프로젝트 전체에서 쓰려면 반드시 Public
으로 선언한다.
Q2. Private 변수를 다른 모듈에서 접근해야 할 때는?
함수를 Public
으로 만들어 래퍼(wrapper) 역할을 하거나, Property 프로시저를 통해 간접적으로 값을 노출한다. 직접 접근은 불가하다.
Q3. Static과 Public을 함께 쓰면 어떤 문제가 생기는가?
Static 변수는 프로시저 실행 컨텍스트 내에만 존재해 충돌 가능성은 낮다. 그러나 동일 기능을 Public 전역 변수로도 유지하면 값 불일치가 발생할 수 있다. 한 가지 패턴만 선택한다.
'#4 VBA > #4.2 코딩문법' 카테고리의 다른 글
변수를 선언하는 Dim 키워드 (0) | 2025.07.28 |
---|---|
변수(Variable) 개념과 역할 (3) | 2025.07.27 |