VBA(Excel) 오류의 적절한 처리
저는 VBA와 꽤 오랫동안 일해 왔지만, 여전히 오류 처리에 대해 잘 모르겠습니다.
좋은 기사는 CPearson.com의 기사입니다.
그러나 지금까지의 에러 처리 방법이 완전히 잘못된 것은 아닌지 아직 의문입니다.블록 1
On Error Goto ErrCatcher
If UBound(.sortedDates) > 0 Then
// Code
Else
ErrCatcher:
// Code
End If
if 구가 true일 경우 실행되며, 실패 시 Goto가 Else 파트로 들어갑니다.어레이의 Ubound가 0 이하가 되어서는 안 되기 때문에 오류 없이 이 방법은 지금까지 매우 잘 작동했습니다.
제가 제대로 이해했다면 다음과 같습니다.
블록 2
On Error Goto ErrCatcher
If Ubound(.sortedDates) > 0 Then
// Code
End If
Goto hereX
ErrCatcher:
//Code
Resume / Resume Next / Resume hereX
hereX:
또는 이렇게도 할 수 있습니다.블록 3
On Error Goto ErrCatcher
If Ubound(.sortedDates) > 0 Then
// Code
End If
ErrCatcher:
If Err.Number <> 0 then
//Code
End If
가장 일반적인 것은 에러 「캐처」는 서브의 끝에 있고, 서브는 실제로 「종료 서브」로 끝나는 것입니다만, 코드를 읽기 위해서 반대로 점프하면, 서브가 큰 것은 조금 혼란스럽지 않습니까?
블록 4
코드 출처: CPearson.com
On Error Goto ErrHandler:
N = 1 / 0 ' cause an error
'
' more code
'
Exit Sub
ErrHandler:
' error handling code'
Resume Next
End Sub
블록 3처럼 해야 하나요?
ray023에서 정말 훌륭한 답변을 받았습니다만, 과잉 살상이라고 하는 코멘트는 적절합니다.'더 가벼운' 버전의 경우...
블록 1은 IMHO, 나쁜 관행입니다.osknows에서 이미 지적했듯이 오류 처리와 일반 경로 코드를 혼합하는 것은 좋지 않습니다.예를 들어, 에러 상태가 실제로 존재하는 동안 새로운 에러가 발생했을 경우, 그 에러를 처리할 기회가 없습니다(실행이 「버블 업」되는 에러 핸들러가 있는 루틴으로부터 호출하지 않는 한).
블록 2는 Try/Catch 블록을 모방한 것 같습니다.괜찮을 것 같은데 VBA Way가 아니에요.블록 3은 블록 2의 변형입니다.
블록 4는 VBA Way의 베어본 버전입니다.코드를 계승하는 다른 VBA 프로그래머가 기대하는 것이기 때문에, 그것을 사용하는 것을 강력히 추천합니다.자, 이제 작은 확장을 설명하겠습니다.
Private Sub DoSomething()
On Error GoTo ErrHandler
'Dim as required
'functional code that might throw errors
ExitSub:
'any always-execute (cleanup?) code goes here -- analagous to a Finally block.
'don't forget to do this -- you don't want to fall into error handling when there's no error
Exit Sub
ErrHandler:
'can Select Case on Err.Number if there are any you want to handle specially
'display to user
MsgBox "Something's wrong: " & vbCrLf & Err.Description
'or use a central DisplayErr routine, written Public in a Module
DisplayErr Err.Number, Err.Description
Resume ExitSub
Resume
End Sub
번째 " " " "는 주의해 주세요.Resume
이것은 최근에 배운 요령입니다.일반 처리에서는 실행되지 않습니다.Resume <label>
스테이트먼트를 지정하면 실행이 다른 곳으로 전송됩니다.하지만 디버깅을 위한 신의 선물일 수도 있습니다.[디버깅] [디버깅] ( [ Ctl - Break ] 、 [ Execution was interrupted ][ Debug ]를( 。 표시은 ''입니다.MsgBox
또는 다음 문구를 참조하십시오. Statement하여 "Set Next Statement"(Ctl-F9)를 강조 합니다.Resume
F8 키를 누릅니다.그러면 오류가 발생한 위치가 정확히 표시됩니다.
이 포맷의 「점핑 어라운드」에 대한 당신의 반대에 대해서는, A)앞에서 설명한 바와 같이 VBA 프로그래머가 기대하는 것과 B) 당신의 루틴은 점프할 수 있을 정도로 짧아야 합니다.
에러 처리의 주된 목적은 다음과 같습니다.
- 예측은 가능하지만 사용자가 실행하지 않도록 제어할 수 없는 트랩 오류(예를 들어, 썸 드라이브가 제거되었을 때 파일을 썸 드라이브에 저장)
- 예기치 않은 오류의 경우 사용자에게 문제가 무엇인지 알려주는 양식을 제공합니다.이렇게 하면 메시지를 전달할 수 있으며 수정 작업을 수행하는 동안 해결 방법을 제공할 수 있습니다.
그럼 어떻게 할 건데?
먼저 예기치 않은 오류가 발생했을 때 표시할 오류 양식을 만듭니다.
frmErrors를 사용하다
다음 라벨에 주의해 주세요.
- lbl 표제
- lbl 소스
- lbl 문제
- lbl Response(응답)
또한 표준 명령 버튼은 다음과 같습니다.
- 무시
- 재시도
- 취소
이 폼의 코드에는 화려한 것이 없습니다.
Option Explicit
Private Sub cmdCancel_Click()
Me.Tag = CMD_CANCEL
Me.Hide
End Sub
Private Sub cmdIgnore_Click()
Me.Tag = CMD_IGNORE
Me.Hide
End Sub
Private Sub cmdRetry_Click()
Me.Tag = CMD_RETRY
Me.Hide
End Sub
Private Sub UserForm_Initialize()
Me.lblErrorTitle.Caption = "Custom Error Title Caption String"
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'Prevent user from closing with the Close box in the title bar.
If CloseMode <> 1 Then
cmdCancel_Click
End If
End Sub
기본적으로 폼이 닫힐 때 사용자가 어떤 버튼을 눌렀는지 알아야 합니다.
다음으로 VBA 앱 전체에서 사용되는 오류 핸들러 모듈을 만듭니다.
'****************************************************************
' MODULE: ErrorHandler
'
' PURPOSE: A VBA Error Handling routine to handle
' any unexpected errors
'
' Date: Name: Description:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'03/22/2010 Ray Initial Creation
'****************************************************************
Option Explicit
Global Const CMD_RETRY = 0
Global Const CMD_IGNORE = 1
Global Const CMD_CANCEL = 2
Global Const CMD_CONTINUE = 3
Type ErrorType
iErrNum As Long
sHeadline As String
sProblemMsg As String
sResponseMsg As String
sErrorSource As String
sErrorDescription As String
iBtnCap(3) As Integer
iBitmap As Integer
End Type
Global gEStruc As ErrorType
Sub EmptyErrStruc_S(utEStruc As ErrorType)
Dim i As Integer
utEStruc.iErrNum = 0
utEStruc.sHeadline = ""
utEStruc.sProblemMsg = ""
utEStruc.sResponseMsg = ""
utEStruc.sErrorSource = ""
For i = 0 To 2
utEStruc.iBtnCap(i) = -1
Next
utEStruc.iBitmap = 1
End Sub
Function FillErrorStruct_F(EStruc As ErrorType) As Boolean
'Must save error text before starting new error handler
'in case we need it later
EStruc.sProblemMsg = Error(EStruc.iErrNum)
On Error GoTo vbDefaultFill
EStruc.sHeadline = "Error " & Format$(EStruc.iErrNum)
EStruc.sProblemMsg = EStruc.sErrorDescription
EStruc.sErrorSource = EStruc.sErrorSource
EStruc.sResponseMsg = "Contact the Company and tell them you received Error # " & Str$(EStruc.iErrNum) & ". You should write down the program function you were using, the record you were working with, and what you were doing."
Select Case EStruc.iErrNum
'Case Error number here
'not sure what numeric errors user will ecounter, but can be implemented here
'e.g.
'EStruc.sHeadline = "Error 3265"
'EStruc.sResponseMsg = "Contact tech support. Tell them what you were doing in the program."
Case Else
EStruc.sHeadline = "Error " & Format$(EStruc.iErrNum) & ": " & EStruc.sErrorDescription
EStruc.sProblemMsg = EStruc.sErrorDescription
End Select
GoTo FillStrucEnd
vbDefaultFill:
'Error Not on file
EStruc.sHeadline = "Error " & Format$(EStruc.iErrNum) & ": Contact Tech Support"
EStruc.sResponseMsg = "Contact the Company and tell them you received Error # " & Str$(EStruc.iErrNum)
FillStrucEnd:
Exit Function
End Function
Function iErrorHandler_F(utEStruc As ErrorType) As Integer
Static sCaption(3) As String
Dim i As Integer
Dim iMCursor As Integer
Beep
'Setup static array
If Len(sCaption(0)) < 1 Then
sCaption(CMD_IGNORE) = "&Ignore"
sCaption(CMD_RETRY) = "&Retry"
sCaption(CMD_CANCEL) = "&Cancel"
sCaption(CMD_CONTINUE) = "Continue"
End If
Load frmErrors
'Did caller pass error info? If not fill struc with the needed info
If Len(utEStruc.sHeadline) < 1 Then
i = FillErrorStruct_F(utEStruc)
End If
frmErrors!lblHeadline.Caption = utEStruc.sHeadline
frmErrors!lblProblem.Caption = utEStruc.sProblemMsg
frmErrors!lblSource.Caption = utEStruc.sErrorSource
frmErrors!lblResponse.Caption = utEStruc.sResponseMsg
frmErrors.Show
iErrorHandler_F = frmErrors.Tag ' Save user response
Unload frmErrors ' Unload and release form
EmptyErrStruc_S utEStruc ' Release memory
End Function
어플리케이션에만 커스텀되는 에러가 발생할 수 있습니다.이것은 통상, 사용의 애플리케이션 전용의 에러의 짧은 리스트입니다.상수 모듈이 아직 없는 경우 사용자 지정 오류의 ENUM을 포함하는 모듈을 만듭니다(참고: Office '97은 ENUMS를 지원하지 않습니다).ENUM은 다음과 같습니다.
Public Enum CustomErrorName
MaskedFilterNotSupported
InvalidMonthNumber
End Enum
커스텀 에러를 발생시키는 모듈을 작성합니다.
'********************************************************************************************************************************
' MODULE: CustomErrorList
'
' PURPOSE: For trapping custom errors applicable to this application
'
'INSTRUCTIONS: To use this module to create your own custom error:
' 1. Add the Name of the Error to the CustomErrorName Enum
' 2. Add a Case Statement to the raiseCustomError Sub
' 3. Call the raiseCustomError Sub in the routine you may see the custom error
' 4. Make sure the routine you call the raiseCustomError has error handling in it
'
'
' Date: Name: Description:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'03/26/2010 Ray Initial Creation
'********************************************************************************************************************************
Option Explicit
Const MICROSOFT_OFFSET = 512 'Microsoft reserves error values between vbObjectError and vbObjectError + 512
'************************************************************************************************
' FUNCTION: raiseCustomError
'
' PURPOSE: Raises a custom error based on the information passed
'
'PARAMETERS: customError - An integer of type CustomErrorName Enum that defines the custom error
' errorSource - The place the error came from
'
' Returns: The ASCII vaule that should be used for the Keypress
'
' Date: Name: Description:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'03/26/2010 Ray Initial Creation
'************************************************************************************************
Public Sub raiseCustomError(customError As Integer, Optional errorSource As String = "")
Dim errorLong As Long
Dim errorDescription As String
errorLong = vbObjectError + MICROSOFT_OFFSET + customError
Select Case customError
Case CustomErrorName.MaskedFilterNotSupported
errorDescription = "The mask filter passed is not supported"
Case CustomErrorName.InvalidMonthNumber
errorDescription = "Invalid Month Number Passed"
Case Else
errorDescription = "The custom error raised is unknown."
End Select
Err.Raise errorLong, errorSource, errorDescription
End Sub
이것으로, 프로그램의 에러를 트랩 할 수 있게 되었습니다.서브(또는 기능)는 다음과 같습니다.
Public Sub MySub(monthNumber as Integer)
On Error GoTo eh
Dim sheetWorkSheet As Worksheet
'Run Some code here
'************************************************
'* OPTIONAL BLOCK 1: Look for a specific error
'************************************************
'Temporarily Turn off Error Handling so that you can check for specific error
On Error Resume Next
'Do some code where you might expect an error. Example below:
Const ERR_SHEET_NOT_FOUND = 9 'This error number is actually subscript out of range, but for this example means the worksheet was not found
Set sheetWorkSheet = Sheets("January")
'Now see if the expected error exists
If Err.Number = ERR_SHEET_NOT_FOUND Then
MsgBox "Hey! The January worksheet is missing. You need to recreate it."
Exit Sub
ElseIf Err.Number <> 0 Then
'Uh oh...there was an error we did not expect so just run basic error handling
GoTo eh
End If
'Finished with predictable errors, turn basic error handling back on:
On Error GoTo eh
'**********************************************************************************
'* End of OPTIONAL BLOCK 1
'**********************************************************************************
'**********************************************************************************
'* OPTIONAL BLOCK 2: Raise (a.k.a. "Throw") a Custom Error if applicable
'**********************************************************************************
If not (monthNumber >=1 and monthnumber <=12) then
raiseCustomError CustomErrorName.InvalidMonthNumber, "My Sub"
end if
'**********************************************************************************
'* End of OPTIONAL BLOCK 2
'**********************************************************************************
'Rest of code in your sub
goto sub_exit
eh:
gEStruc.iErrNum = Err.Number
gEStruc.sErrorDescription = Err.Description
gEStruc.sErrorSource = Err.Source
m_rc = iErrorHandler_F(gEStruc)
If m_rc = CMD_RETRY Then
Resume
End If
sub_exit:
'Any final processing you want to do.
'Be careful with what you put here because if it errors out, the error rolls up. This can be difficult to debug; especially if calling routine has no error handling.
Exit Sub 'I was told a long time ago (10+ years) that exit sub was better than end sub...I can't tell you why, so you may not want to put in this line of code. It's habit I can't break :P
End Sub
위의 코드를 복사/붙여넣으면 바로 사용할 수 없지만, 반드시 요점을 알려드립니다.
저는 Block1을 절대 안 써요.Errors와 무관한 IF 문에 Error 블록을 두는 것은 옳지 않은 것 같습니다.
블록 2, 3, 4는 테마의 변형인 것 같아요.GOTO 스테이트먼트를 싫어하기 때문에 Block 3 & 4를 2보다 사용하는 것을 선호합니다.일반적으로 Block 4 방식을 사용합니다.이것은 Microsoft ActiveX Data Objects 2.8 라이브러리가 추가되었는지, 추가되지 않은 경우 2.8이 없는 경우 이전 버전을 추가하거나 사용하기 위해 사용하는 코드의 예입니다.
Option Explicit
Public booRefAdded As Boolean 'one time check for references
Public Sub Add_References()
Dim lngDLLmsadoFIND As Long
If Not booRefAdded Then
lngDLLmsadoFIND = 28 ' load msado28.tlb, if cannot find step down versions until found
On Error GoTo RefErr:
'Add Microsoft ActiveX Data Objects 2.8
Application.VBE.ActiveVBProject.references.AddFromFile _
Environ("CommonProgramFiles") + "\System\ado\msado" & lngDLLmsadoFIND & ".tlb"
On Error GoTo 0
Exit Sub
RefErr:
Select Case Err.Number
Case 0
'no error
Case 1004
'Enable Trust Centre Settings
MsgBox ("Certain VBA References are not available, to allow access follow these steps" & Chr(10) & _
"Goto Excel Options/Trust Centre/Trust Centre Security/Macro Settings" & Chr(10) & _
"1. Tick - 'Disable all macros with notification'" & Chr(10) & _
"2. Tick - 'Trust access to the VBA project objects model'")
End
Case 32813
'Err.Number 32813 means reference already added
Case 48
'Reference doesn't exist
If lngDLLmsadoFIND = 0 Then
MsgBox ("Cannot Find Required Reference")
End
Else
For lngDLLmsadoFIND = lngDLLmsadoFIND - 1 To 0 Step -1
Resume
Next lngDLLmsadoFIND
End If
Case Else
MsgBox Err.Number & vbCrLf & Err.Description, vbCritical, "Error!"
End
End Select
On Error GoTo 0
End If
booRefAdded = TRUE
End Sub
나는 일을 단순하게 한다.
모듈 레벨에서 2개의 변수를 정의하고 1개의 변수를 모듈 이름으로 설정합니다.
Private Const ThisModuleName As String = "mod_Custom_Functions"
Public sLocalErrorMsg As String
모듈의 각 하위/기능 내에서 로컬 변수를 정의합니다.
Dim ThisRoutineName As String
ThisRoutineName을 서브 또는 함수의 이름으로 설정했습니다.
' Housekeeping
On Error Goto ERR_RTN
ThisRoutineName = "CopyWorksheet"
그런 다음 모든 오류를 ERR_로 보냅니다.RTN: 발생 시 먼저 sLocalErrorMsg를 설정하여 실제 오류를 정의하고 디버깅 정보를 제공합니다.
If Len(Trim(FromWorksheetName)) < 1 Then
sLocalErrorMsg = "Parameter 'FromWorksheetName' Is Missing."
GoTo ERR_RTN
End If
각 하위/함수의 하단에서 다음과 같이 논리 흐름을 지시합니다.
'
' The "normal" logic goes here for what the routine does
'
GoTo EXIT_RTN
ERR_RTN:
On Error Resume Next
' Call error handler if we went this far.
ErrorHandler ThisModuleName, ThisRoutineName, sLocalErrorMsg, Err.Description, Err.Number, False
EXIT_RTN:
On Error Resume Next
'
' Some closing logic
'
End If
다음으로 "mod_Error_Handler"라고 하는 다른 모듈을 모든 프로젝트에 투입합니다.
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Subroutine Name: ErrorHandler '
' '
' Description: '
' This module will handle the common error alerts. '
' '
' Inputs: '
' ModuleName String 'The name of the module error is in. '
' RoutineName String 'The name of the routine error in in. '
' LocalErrorMsg String 'A local message to assist with troubleshooting.'
' ERRDescription String 'The Windows Error Description. '
' ERRCode Long 'The Windows Error Code. '
' Terminate Boolean 'End program if error encountered? '
' '
' Revision History: '
' Date (YYYYMMDD) Author Change '
' =============== ===================== =============================================== '
' 20140529 XXXXX X. XXXXX Original '
' '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
Public Sub ErrorHandler(ModuleName As String, RoutineName As String, LocalErrorMsg As String, ERRDescription As String, ERRCode As Long, Terminate As Boolean)
Dim sBuildErrorMsg As String
' Build Error Message To Display
sBuildErrorMsg = "Error Information:" & vbCrLf & vbCrLf
If Len(Trim(ModuleName)) < 1 Then
ModuleName = "Unknown"
End If
If Len(Trim(RoutineName)) < 1 Then
RoutineName = "Unknown"
End If
sBuildErrorMsg = sBuildErrorMsg & "Module Name: " & ModuleName & vbCrLf & vbCrLf
sBuildErrorMsg = sBuildErrorMsg & "Routine Name: " & RoutineName & vbCrLf & vbCrLf
If Len(Trim(LocalErrorMsg)) > 0 Then
sBuildErrorMsg = sBuildErrorMsg & "Local Error Msg: " & LocalErrorMsg & vbCrLf & vbCrLf
End If
If Len(Trim(ERRDescription)) > 0 Then
sBuildErrorMsg = sBuildErrorMsg & "Program Error Msg: " & ERRDescription & vbCrLf & vbCrLf
If IsNumeric(ERRCode) Then
sBuildErrorMsg = sBuildErrorMsg & "Program Error Code: " & Trim(Str(ERRCode)) & vbCrLf & vbCrLf
End If
End If
MsgBox sBuildErrorMsg, vbOKOnly + vbExclamation, "Error Detected!"
If Terminate Then
End
End If
End Sub
최종 결과는 팝업에러 메시지입니다.이 메시지는 어떤 모듈에서 어떤 soubroutine에서 구체적으로 어떤 에러 메시지였는지를 나타냅니다.또, Windows 에러 메세지와 코드도 삽입합니다.
블록 2는 에러 핸들러를 리셋 하지 않기 때문에 기능하지 않습니다.그 때문에, 무한 루프가 발생할 가능성이 있습니다.에러 처리를 VBA에서 올바르게 동작시키려면 , 다음의 조작이 필요합니다.Resume
에러 핸들러를 클리어하기 위한 스테이트먼트입니다.그Resume
는 이전의 에러 핸들러도 재활성화합니다.새로운 에러가 이전의 에러 핸들러로 돌아와 무한 루프가 발생하기 때문에 블록2가 실패합니다.
블록 3이 없기 때문에 실패한다.Resume
그 후 오류 처리를 시도하면 실패합니다.
모든 오류 핸들러는 절차를 종료하거나Resume
진술.에러 핸들러에 대해서 통상의 실행을 라우팅 하는 것은 혼란스럽습니다.그렇기 때문에 보통 에러 핸들러는 맨 아래에 있습니다.
그러나 VBA의 오류를 처리하는 다른 방법이 있습니다.VB.net의 Try/Catch와 같은 인라인 방식으로 오류를 처리합니다.몇 가지 함정이 있지만 적절하게 관리하면 상당히 잘 작동합니다.
Sub InLineErrorHandling()
'code without error handling
BeginTry1:
'activate inline error handler
On Error GoTo ErrHandler1
'code block that may result in an error
Dim a As String: a = "Abc"
Dim c As Integer: c = a 'type mismatch
ErrHandler1:
'handle the error
If Err.Number <> 0 Then
'the error handler has deactivated the previous error handler
MsgBox (Err.Description)
'Resume (or exit procedure) is the only way to get out of an error handling block
'otherwise the following On Error statements will have no effect
'CAUTION: it also reactivates the previous error handler
Resume EndTry1
End If
EndTry1:
'CAUTION: since the Resume statement reactivates the previous error handler
'you must ALWAYS use an On Error GoTo statement here
'because another error here would cause an endless loop
'use On Error GoTo 0 or On Error GoTo <Label>
On Error GoTo 0
'more code with or without error handling
End Sub
출처:
- http://www.cpearson.com/excel/errorhandling.htm
- http://msdn.microsoft.com/en-us/library/bb258159.aspx
이 작업을 수행하기 위한 열쇠는Resume
바로 뒤에 이어지는 성명On Error
진술.그Resume
에러 핸들러내에 있어, 코드를 로 변환합니다.EndTry1
라벨. 즉시 다른 라벨을 설정해야 합니다.On Error
이전 에러 핸들러가 「실패」하기 때문에, 문제를 회피하는 스테이트먼트입니다.즉, 활성화되어 다른 오류를 처리할 준비가 됩니다.이로 인해 오류가 반복되어 무한 루프 상태가 될 수 있습니다.
핸들러를 , 「 」를 설정할 .On Error
「」를 사용합니다.On Error Goto 0
모든 오류 처리를 취소합니다.
이것이 내일 학생들에게 가르칠 내용입니다.몇 년 동안 이걸 보고...즉, http://www.cpearson.com/excel/errorhandling.htm 위의 모든 문서는 뛰어난 것으로 생각됩니다.
다른 분들을 위해서 요약이 됐으면 좋겠어요. 게 있어요.Err
또는 inactive) 。ErrorHandler
둘 다 새로운 오류에 대처하고 리셋해야 합니다.
워크북에 붙여넣고 F8을 사용하여 단계를 수행합니다.
Sub ErrorHandlingDemonstration()
On Error GoTo ErrorHandler
'this will error
Debug.Print (1 / 0)
'this will also error
dummy = Application.WorksheetFunction.VLookup("not gonna find me", Range("A1:B2"), 2, True)
'silly error
Dummy2 = "string" * 50
Exit Sub
zeroDivisionErrorBlock:
maybeWe = "did some cleanup on variables that shouldnt have been divided!"
' moves the code execution to the line AFTER the one that errored
Resume Next
vlookupFailedErrorBlock:
maybeThisTime = "we made sure the value we were looking for was in the range!"
' moves the code execution to the line AFTER the one that errored
Resume Next
catchAllUnhandledErrors:
MsgBox(thisErrorsDescription)
Exit Sub
ErrorHandler:
thisErrorsNumberBeforeReset = Err.Number
thisErrorsDescription = Err.Description
'this will reset the error object and error handling
On Error GoTo 0
'this will tell vba where to go for new errors, ie the new ErrorHandler that was previous just reset!
On Error GoTo ErrorHandler
' 11 is the err.number for division by 0
If thisErrorsNumberBeforeReset = 11 Then
GoTo zeroDivisionErrorBlock
' 1004 is the err.number for vlookup failing
ElseIf thisErrorsNumberBeforeReset = 1004 Then
GoTo vlookupFailedErrorBlock
Else
GoTo catchAllUnhandledErrors
End If
End Sub
언급URL : https://stackoverflow.com/questions/6028288/properly-handling-errors-in-vba-excel
'bestsource' 카테고리의 다른 글
WPF의 목록 상자 항목을 선택할 수 없도록 설정 (0) | 2023.04.09 |
---|---|
의미 문제: 자산의 합성된 getter는 '소유' 객체를 반환하기 위한 코코아 명명 규칙을 따릅니다. (0) | 2023.04.09 |
WPF 라운드 코너 컨테이너를 작성하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
iOS info.plist 파일 내의 문자열을 현지화하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
프리태그에 텍스트를 줄 바꿈하려면 어떻게 해야 합니까? (0) | 2023.04.09 |