VBA On Error – 오류 처리 예제
In this Article
VBA 오류 치트시트
Errors 설명
더 많은 VBA “치트 시트” 및 무료 PDF 다운로드 보기
VBA 오류 처리
VBA 오류 처리는 VBA 런타임 오류를 예상, 감지 및 해결하는 프로세스입니다. VBA 오류 처리 프로세스는 오류가 실제로 발생하기 전인 코드를 작성할 때 실행합니다.
VBA 런타임 오류는 코드 실행 중에 발생하는 오류입니다. 런타임 오류의 예는 다음과 같습니다:
- 존재하지 않는 통합 문서, 워크시트 또는 기타 객체 참조(런타임 오류 1004)
- 잘못된 데이터(예: 오류가 포함된 Excel 셀 참조)(유형 불일치 – 런타임 오류 13)
- 0으로 나눌 경우
VBA On Error 구문
대부분의 VBA 오류 처리는 On Error 문으로 수행됩니다. On Error 문은 오류가 발생했을 때 수행해야 할 작업을 VBA에 알려줍니다. 아래와 같이 세 가지 On Error 문이 있습니다:
- On Error GoTo 0
- On Error Resume Next
- On Error GoTo Line
On Error GoTo 0
On Error GoTo 0 은 VBA의 기본 설정값 입니다. 설정값이 변경되었을 경우 다음 코드를 추가하여 이 기본 설정으로 복원할 수 있습니다:
On Error GoTo 0
On Error GoTo 0로 설정된 상태에서 오류가 발생하면 VBA는 코드 실행을 중지하고 오류 메시지 박스를 표시합니다.
On Error Resume Next 오류처리(다음 섹션에서 설명)를 설정한 후에 On Error GoTo 0 코드를 추가하는 경우가 많습니다:
Sub ErrorGoTo0()
On Error Resume Next
ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0
'이후 코드 실행
End Sub
On Error Resume Next
On Error Resume Next 는 오류가 포함된 코드를 건너뛰고 다음 코드를 진행합니다.
On Error Resume Next
참고: On Error Resume Next는오류를 수정하거나 다른 방법으로 해결하지 않습니다. 단순히 오류가 포함된 코드가 존재하지 않는 것처럼 계속 진행하도록 VBA에 지시할 뿐입니다. On Error Resume Next를 잘못 사용하면 의도하지 않은 결과를 초래할 수 있습니다.
On Error Resume Next는 존재 여부가 불투명한 객체로 작업할 때 사용하면 좋습니다. 예를 들어 도형을 삭제하는 코드를 작성하고 싶지만 도형이 이미 삭제된 상태에서 코드를 실행하면 VBA에서 오류가 발생합니다. 이럴때 On Error Resume Next를 사용하면 도형이 있는 경우에만 VBA에 삭제하도록 지시할 수 있습니다.
On Error Resume Next
ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0
잠재적으로 오류가 발생할 수 있는 포함된 코드 줄 뒤에 On Error GoTo 0을 추가한 것이 보이실 것입니다. 이렇게 하면 오류 처리가 재설정됩니다.
다음 섹션에서는 Err.Number를 사용하여 오류가 발생했는지 테스트하는 방법을 보여드리겠습니다. 이 기능은 고급 오류 처리 옵션을 제공합니다.
Err.Number, Err.Clear, 오류 감지하기
오류가 포함된 줄을 단순히 건너뛰는 대신 On Error Resume Next 와 Err.Number를 사용하여 오류를 감지할 수 있습니다.
Err.Number는 감지된 오류 유형에 해당하는 오류 번호를 반환합니다. 오류가 없으면 Err.Number = 0입니다.
예를 들어, 아래 프로시저는 발생한 오류가 런타임 오류 ’11’이므로 “11”을 반환합니다.
Sub ErrorNumber_ex()
On Error Resume Next
ActiveCell.Value = 2 / 0
MsgBox Err.Number
End Sub
Err.Number로 오류처리하기
Err.Number의 목적은 오류가 발생했는지 감지하는 기능에 있습니다(Err.Number <> 0). 아래 예제에서는 Err.Number를 사용하여 시트가 존재하는지 테스트하는 함수를 만들었습니다.
Sub TestWS()
MsgBox DoesWSExist("test")
End Sub
Function DoesWSExist(wsName As String) As Boolean
Dim ws As Worksheet
On Error Resume Next
Set ws = Sheets(wsName)
'If Error WS Does not exist
If Err.Number <> 0 Then
DoesWSExist = False
Else
DoesWSExist = True
End If
On Error GoTo -1
End Function
참고: 마지막에 Err.Number를 0으로 재설정하는 On Error GoTo -1을 추가했습니다(아래 두 섹션에서 추가 설명 드릴 예정입니다).
On Error Resume Next 및 Err.Number를 사용하면 다른 프로그래밍 언어의 “Try” & “Catch” 기능을 사용할 수 있습니다.
On Error GoTo Line
On Error GoTo Line은 오류가 발생하면 레이블로 지정된 코드 줄로 “이동”하도록 VBA에 지시합니다. 다음과 같이 Go To 문을 선언합니다(여기서 errHandler는 이동할 줄 레이블입니다):
On Error GoTo errHandler
를 선언하고 다음과 같이 이동할 코드 줄에 레이블을 만듭니다:
errHandler:
참고: 이 레이블은 일반 VBA GoTo 문에서 사용하는 것과 동일한 레이블입니다.
아래에서는 On Error GoTo Line을 사용하여 프로시저를 종료하는 방법을 보여드리겠습니다.
오류 발생시 서브프로시저 종료하기
오류 발생 시 On Error GoTo Line을 사용하여 서브 프로시저를 종료할 수 있습니다.
프로시저 끝에 오류 발생시 이동할 레이블을 배치하여 이 작업을 수행할 수 있습니다:
Sub ErrGoToEnd()
On Error GoTo endProc
'실행할 코드
endProc:
End Sub
또는 Exit Sub 명령어를 사용하여 구현할 수 있습니다:
Sub ErrGoToEnd()
On Error GoTo endProc
'실행할 코드
GoTo skipExit
endProc:
Exit Sub
skipExit:
'실행할 코드
End Sub
Err.Clear, On Error GoTo -1, Err.Number 재설정하기
오류가 처리된 후에는 일반적으로 향후 오류 처리와 관련된 문제가 발생하지 않도록오류를 삭제합니다.
오류가 발생한 후 Err.Clear와 On Error GoTo -1을 모두 사용하여 Err.Number를 0으로 재설정할 수 있습니다. 하지만 한 가지 중요한 차이점이 있습니다: Err.Clear는 실제 오류 자체를 재설정하는 것이 아니라 Err.Number만 재설정합니다.
무슨 뜻인지 궁금하신가요? Err.Clear를 사용하면 오류 처리 설정을 변경할 수 없습니다. 차이점을 확인하려면 아래 코드를 테스트하고 On Error GoTo -1을 Err.Clear로 바꾸세요:
Sub ErrExamples()
On Error GoTo errHandler:
'"Application-defined" error
Error (13)
Exit Sub
errHandler:
' Clear Error
On Error GoTo -1
On Error GoTo errHandler2:
'"Type mismatch" error
Error (1034)
Exit Sub
errHandler2:
Debug.Print Err.Description
End Sub
일반적으로 Err.Clear를 사용해야 할 특별한 이유가 없는 한 항상 On Error GoTo -1을 사용하는 것을 추천합니다.
VBA On Error MsgBox
오류 시 메시지 박스를 표시할 수도 있습니다. 이 예제에서는 오류가 발생하는 위치에 따라 다른 메시지 상자를 표시합니다:
Sub ErrorMessageEx()
Dim errMsg As String
On Error GoTo errHandler
'1단계
errMsg = "An error occured during the Copy & Paste stage."
'Err.Raise (11)
'2단계
errMsg = "An error occured during the Data Validation stage."
'Err.Raise (11)
'3단계
errMsg = "An error occured during the P&L-Building and Copy-Over stage."
Err.Raise (11)
'4단계
errMsg = "An error occured while attempting to log the Import on the Setup Page"
'Err.Raise (11)
GoTo endProc
errHandler:
MsgBox errMsg
endProc:
End Sub
각각의 경우를 살펴보기 위해 실행하고자 하는 단계의 Err.Raise(11)을 활성 코드로 바꾸면 됩니다.
VBA IsError
오류를 처리하는 또 다른 방법은 VBA ISERROR 함수를 사용하여 오류를 테스트하는 것입니다. ISERROR 함수는 표현식에 오류가 있는지 테스트하여 오류가 발생하면 TRUE 또는 FALSE를 반환합니다.
Sub IsErrorEx()
MsgBox IsError(Range("a7").Value)
End Sub
If Error VBA
Excel IFERROR 함수를 사용하여 VBA에서 오류를 처리할 수도 있습니다. IFERROR 함수는 WorksheetFunction 클래스를 사용하여 액세스해야 합니다:
Sub IfErrorEx()
Dim n As Long
n = WorksheetFunction.IfError(Range("a10").Value, 0)
MsgBox n
End Sub
그러면 범위 A10의 값이 출력되며, 값이 오류인 경우 0을 출력합니다.
VBA Error Types
런타임 오류
위에서 설명한 바와 같이:
VBA 런타임 오류는 코드 실행 중에 발생하는 오류입니다. 런타임 오류의 예는 다음과 같습니다:
- 존재하지 않는 통합 문서, 워크시트 또는 기타 객체 참조
- 잘못된 데이터(예: 오류가 포함된 Excel 셀 참조)
- 0으로 나눌 경우
위에서 설명한 방법을 사용하여 런타임 오류를 ‘오류 처리’할 수 있습니다.
구문 오류
VBA 구문 오류는 코드 작성 시 발생하는 오류입니다. 구문 오류의 예는 다음과 같습니다:
- 맞춤법 오류
- 구두점이 없거나 잘못됨
VBA 편집기는 구문 오류를 빨간색으로 강조 표시하여 구분합니다:
VBA 편집기에는 ‘자동 구문 검사’ 옵션도 있습니다:
이 옵션을 선택하고 구문 오류가 포함된 코드 한 줄을 입력하면 VBA 편집기에서 구문 오류를 경고하는 메시지 박스를 생성합니다:
저는 개인적으로 이 기능이 불편해서 이 기능을 비활성화했습니다.
컴파일 오류
프로시저를 실행하기 전에 VBA는 프로시저를 “컴파일”합니다. 컴파일은 프로그램을 소스 코드(사용자가 볼 수 있는)에서 실행 가능한 형식(사용자가 볼 수 없는)으로 변환합니다.
VBA 컴파일 오류는 코드가 컴파일되지 못하게 하는 오류입니다.
아래와 같은 상황에서 컴파일 오류가 발생할 수 있습니다:
- Next가 없는 For 문 without Next
- End Select가 없는 Select 문
- End If가 없는 If문
- 존재하지 않는 프로시저를 호출할 경우
구문 오류(이전 섹션에서 설명)는 컴파일 오류의 일종입니다.
디버그 > 컴파일
프로시저를 실행하려고 할 때 컴파일 오류가 나타납니다. 하지만 프로시저를 실행하기 전에 컴파일 오류를 식별하는 것이 가장 이상적입니다.
프로젝트를 미리 컴파일하면 이 작업을 수행할 수 있습니다. 이 작업을 수행하려면 디버그 > VBA Project 컴파일로 이동합니다.
컴파일러가 첫 번째 오류로 ‘이동’합니다. 해당 오류를 수정한 후 VBA Project 컴파일을 다시 실행합니다. 모든 오류가 수정될 때까지 이 과정을 반복합니다.
VBA Project 컴파일 메뉴가 회색으로 표시되면 모든 오류가 수정되었음을 알 수 있습니다:
OverFlow 오류
VBA 오버플로우 오류는 너무 큰 값을 변수에 넣으려고 할 때 발생합니다. 예를 들어 Integer 변수는 -32,768에서 32,768 사이의 값만 포함할 수 있습니다. 이보다 큰 값을 입력하면 오버플로 오류가 발생합니다:
이 경우 Long 변수를 사용하여 더 큰 숫자를 저장할 수 있습니다.
기타 VBA 오류
VBA 오류 감지
다른 프로그래밍 언어와 달리 VBA에는 Catch 문이 없습니다. 그러나 오류 발생 시 다음 재개 및 If Err.Number <> 0 Then을 사용하여 Catch 문처럼 사용 할 수 있습니다. 이에 대해서는 위의 Err.Number를 사용한 오류 처리에서 다루었습니다.
VBA 오류 무시
VBA에서 오류를 무시하려면 On Error Resume Next 문을 사용하면 됩니다:
On Error Resume Next
그러나 위에서 언급했듯이 이 문은 오류를 수정하는 것이 아니라 오류가 포함된 코드 줄을 무시할 뿐이므로 주의해서 사용해야 합니다.
VBA 오류 발생시키기 / Err.Raise
VBA에서 오류를 발생시키려면 Err.Raise 메서드를 사용합니다.
이 코드 줄은 런타임 오류 ’13’을 발생시킵니다: 유형 불일치:
Err.Raise (13)
VBA 오류 트래핑
VBA 오류 트래핑은 VBA 오류 처리의 다른 용어일 뿐입니다.
VBA 오류 메시지
VBA 오류 메시지는 다음과 같습니다:
‘디버그’를 클릭하면 오류를 발생시키는 코드 위치를 볼 수 있습니다:
VBA 반복문에서 오류 처리하기
반복문 내에서 오류를 처리하는 가장 좋은 방법은 오류 발생 여부를 감지하기 위해 Err.Number와 함께 On Error Resume Next을 사용하는 것입니다(오류 발생 후 오류를 지우려면 Err.Clear를 사용해야 함을 잊지 마세요).
아래 예제는 두 개의 숫자(A열을 B열로)를 나누고 그 결과를 C열에 출력합니다. 오류가 발생하면 결과는 0이 됩니다.
Sub test()
Dim cell As Range
On Error Resume Next
For Each cell In Range("a1:a10")
'셀 값 설정
cell.Offset(0, 2).Value = cell.Value / cell.Offset(0, 1).Value
'Cell.Value가 오류이면 0으로 설정합니다
If Err.Number <> 0 Then
cell.Offset(0, 2).Value = 0
Err.Clear
End If
Next
End Sub
Access에서 VBA 오류 처리
위의 모든 예제는 Excel VBA에서와 마찬가지로 Access VBA에서도 똑같이 작동합니다.
Function DelRecord(frm As Form)
'이 함수는 폼에서 테이블의 레코드를 삭제하는 데 사용됩니다.
On Error GoTo ending
With frm
If .NewRecord Then
.Undo
Exit Function
End If
End With
With frm.RecordsetClone
.Bookmark = frm.Bookmark
.Delete
frm.Requery
End With
Exit Function
ending:
End
End Function