我正在重新调整我的代码,加入错误处理。然而,有很多我不理解的地方。我特别需要知道如何在函数中正确使用它。我使用Bovey的错误处理程序的重新抛出版本(在底部)。当我开始时,我使用基本的布尔值(非重新抛出)方法,并将我的子程序转换为布尔函数。(附言:根据答案,我将切换回布尔方法。)
我需要指导如何将函数融入到这个方案中。我希望它们能返回它们的真实值(例如字符串或双精度数),或者在某些情况下失败时返回-1,这样我就可以将它们嵌套在其他函数中,而不仅仅返回一个错误处理布尔值。
这是一个典型的对
bDrawCellBorders(myWS)
进行子程序调用的示例,它看起来在入口点内工作得很好。(也就是说,它是一个只被转换为函数的子程序,以便它可以返回一个布尔值给错误处理方案。)Sub UpdateMe() ' Entry Point
Const sSOURCE As String = "UpdateMe()"
On Error GoTo ErrorHandler
Set myWS = ActiveCell.Worksheet
Set myRange = ActiveCell
myWS.Unprotect
' lots of code
If Not bDrawCellBorders(myWS) Then ERR.Raise glHANDLED_ERROR ' Call subroutine
' lots of code
ErrorExit:
On Error Resume Next
Application.EnableEvents = True
myWS.Protect AllowFormattingColumns:=True
Exit Sub
ErrorHandler:
If bCentralErrorHandler(msMODULE, sSOURCE,,True) Then ' Call as Entry Point
Stop
Resume
Else
Resume ErrorExit
End If
End Sub
然而,我不知道如何将这个扩展到真实的函数。这是基于书中的一个例子,该例子是为一个子程序编写的,我只是将其改成了一个函数。
问题:
- 我该如何调用它?就像
x = sngDoSomeMath(17)
这样简单吗?
- 它的错误处理会正常工作吗?
- 在哪里或哪些地方应该使用 bReThrow=true
调用错误处理程序?代码:
Public Function sngDoSomeMath(ByVal iNum As Integer) As Single
Dim sngResult As Single
Const sSOURCE As String = "sngDoSomeMath()"
On Error GoTo ErrorHandler
' example 1, input did not pass validation. don't want to
' go up the error stack but just inform the
' calling program that they didn't get a good result from this
' function call so they can do something else
If iNum <> 42 Then
sngResult = -1 'function failed because I only like the number 42
GoTo ExitHere
End If
' example 2, true error generated
sngResult = iNum / 0
sngDoSomeMath = lResult
ExitHere:
Exit Function
ErrorHandler:
' Run cleanup code
' ... here if any
' Then do error handling
If bCentralErrorHandler(msMODULE, sSOURCE, , , True) Then ' The true is for RETHROW
Stop
Resume
End If
End Function
错误处理程序例程:
'
' Description: This module contains the central error
' handler and related constant declarations.
'
' Authors: Rob Bovey, www.appspro.com
' Stephen Bullen, www.oaltd.co.uk
'
' Chapter Change Overview
' Ch# Comment
' --------------------------------------------------------------
' 15 Initial version
'
Option Explicit
Option Private Module
' **************************************************************
' Global Constant Declarations Follow
' **************************************************************
Public Const gbDEBUG_MODE As Boolean = False ' True enables debug mode, False disables it.
Public Const glHANDLED_ERROR As Long = 9999 ' Run-time error number for our custom errors.
Public Const glUSER_CANCEL As Long = 18 ' The error number generated when the user cancels program execution.
' **************************************************************
' Module Constant Declarations Follow
' **************************************************************
Private Const msSILENT_ERROR As String = "UserCancel" ' Used by the central error handler to bail out silently on user cancel.
Private Const msFILE_ERROR_LOG As String = "Error.log" ' The name of the file where error messages will be logged to.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Comments: This is the central error handling procedure for the
' program. It logs and displays any run-time errors
' that occur during program execution.
'
' Arguments: sModule The module in which the error occured.
' sProc The procedure in which the error occured.
' sFile (Optional) For multiple-workbook
' projects this is the name of the
' workbook in which the error occured.
' bEntryPoint (Optional) True if this call is
' being made from an entry point
' procedure. If so, an error message
' will be displayed to the user.
'
' Returns: Boolean True if the program is in debug
' mode, False if it is not.
'
' Date Developer Chap Action
' --------------------------------------------------------------
' 03/30/08 Rob Bovey Ch15 Initial version
'
Public Function bCentralErrorHandler( _
ByVal sModule As String, _
ByVal sProc As String, _
Optional ByVal sFile As String, _
Optional ByVal bEntryPoint As Boolean, _
Optional ByVal bReThrow As Boolean = True) As Boolean
Static sErrMsg As String
Dim iFile As Integer
Dim lErrNum As Long
Dim sFullSource As String
Dim sPath As String
Dim sLogText As String
' Grab the error info before it's cleared by
' On Error Resume Next below.
lErrNum = ERR.Number
' If this is a user cancel, set the silent error flag
' message. This will cause the error to be ignored.
If lErrNum = glUSER_CANCEL Then sErrMsg = msSILENT_ERROR
' If this is the originating error, the static error
' message variable will be empty. In that case, store
' the originating error message in the static variable.
If Len(sErrMsg) = 0 Then sErrMsg = ERR.Description
' We cannot allow errors in the central error handler.
On Error Resume Next
' Load the default filename if required.
If Len(sFile) = 0 Then sFile = ThisWorkbook.Name
' Get the application directory.
sPath = ThisWorkbook.Path
If Right$(sPath, 1) <> "\" Then sPath = sPath & "\"
' Construct the fully-qualified error source name.
sFullSource = "[" & sFile & "]" & sModule & "." & sProc
' Create the error text to be logged.
sLogText = " " & sFullSource & ", Error " & _
CStr(lErrNum) & ": " & sErrMsg
' Open the log file, write out the error information and
' close the log file.
iFile = FreeFile()
Open sPath & msFILE_ERROR_LOG For Append As #iFile
Print #iFile, Format$(Now(), "mm/dd/yy hh:mm:ss"); sLogText
If bEntryPoint Or Not bReThrow Then Print #iFile,
Close #iFile
' Do not display or debug silent errors.
If sErrMsg <> msSILENT_ERROR Then
' Show the error message when we reach the entry point
' procedure or immediately if we are in debug mode.
If bEntryPoint Or gbDEBUG_MODE Then
Application.ScreenUpdating = True
MsgBox sErrMsg, vbCritical, gsAPP_NAME
' Clear the static error message variable once
' we've reached the entry point so that we're ready
' to handle the next error.
sErrMsg = vbNullString
End If
' The return vale is the debug mode status.
bCentralErrorHandler = gbDEBUG_MODE
Else
' If this is a silent error, clear the static error
' message variable when we reach the entry point.
If bEntryPoint Then sErrMsg = vbNullString
bCentralErrorHandler = False
End If
'If we're using re-throw error handling,
'this is not the entry point and we're not debugging,
're-raise the error, to be caught in the next procedure
'up the call stack.
'Procedures that handle their own errors can call the
'central error handler with bReThrow = False to log the
'error, but not re-raise it.
If bReThrow Then
If Not bEntryPoint And Not gbDEBUG_MODE Then
On Error GoTo 0
ERR.Raise lErrNum, sFullSource, sErrMsg
End If
Else
'Error is being logged and handled,
'so clear the static error message variable
sErrMsg = vbNullString
End If
End Function