我在MS Access中编写了一些VBA,尽管我的问题原理同样适用于Excel或Word VBA。我编写了一个函数GetStringParameterFromTable,它返回一个字符串值。尽管我尽最大努力编写它,但该功能可能会导致VBA生成的错误。如果发生错误,我不希望代码崩溃,所以我必须使用错误处理。但是,我不希望代码显示错误消息,如果出现错误则在函数内停止。我希望函数完成执行并将控制权返回给调用过程,然后我希望调用过程显示错误消息并整理,例如,关闭打开的文件。我的问题是:调用过程如何知道它调用的函数中存在错误,以及它如何获取错误消息?
我想到了三种实现方法:
(1)将GetStringParameterFromTable变为Sub,并通过引用传递ParameterValue,ErrorFlag和ErrorMessage。
(2)将GetStringParameterFromTable保存为Function,将ErrorFlag和ErrorMessage定义为全局变量,并使用alter ErrorFlag和ErrorMessage函数。
(3)将GetStringParameterFromTable保留为Function并定义一个包含三个组件的类型 - ParameterValue,ErrorFlag和ErrorMessage - 并使GetStringParameterFromTable返回我定义的类型的值。
我认为我的要求必须非常普遍,但我找不到任何实施方式的例子。有没有人对我的哪些建议是最好的方式有任何看法,或者是否有更好的方法我没有想到?
自从C#.net实现了Tuples以来,我一直在考虑同样的事情。我使用VBA的type
实现了元组来创建我的元组。我所做的是以下内容:
Public Type myTuple
Value as String 'Or whatever type your value needs to be
ErrCode as Long
ErrDesc as String
End Type
Public Function DoWork (ByRef mObject as MyClass) as myTuple
Dim retVal as myTuple
'Do whatever work
If Err.Number <> 0 then
retVal.Value = Nothing
retVal.ErrNumber = Err.Number
retVal.ErrDesc = Err.Description
Else
Set retVal.Value = Whatever Makes Sense
retVal.ErrNumber = 0
retVal.ErrDesc = VbNullString
End If
DoWork = retVal
End Function
我想更具体一点,但你没有提供代码示例。
我这样做并将错误记录在表中:
' Lookups Replacements
'---------------------
Function DLook(Expression As String, Domain As String, Optional Criteria) As Variant
On Error GoTo Err_Handler
Dim strSQL As String
strSQL = "SELECT " & Expression & " FROM " & Domain 'DLookup
'DCount: strSQL = "SELECT COUNT(" & Expression & ") FROM " & Domain
'DMax: strSQL = "SELECT MAX(" & Expression & ") FROM " & Domain
'DMin: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DFirst: strSQL = "SELECT FIRST(" & Expression & ") FROM " & Domain
'DLast: strSQL = "SELECT LAST(" & Expression & ") FROM " & Domain
'DSum: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DAvg: strSQL = "SELECT AVG(" & Expression & ") FROM " & Domain
If Not IsMissing(Criteria) Then strSQL = strSQL & " WHERE " & Criteria
DLook = DBEngine(0)(0).OpenRecordset(strSQL, dbOpenForwardOnly)(0)
Exit Function
Err_Handler:
'Can be made as Error Sub as well
Dim ErrNumber as Integer
Dim ErrDescription as String
ErrNumber = Err.Number
ErrDescription = Err.Description
Err.Clear
On Error Resume Next
Dim strSQL as String
strSQL = "INSERT INTO tblErrorLog (ErrorNumber, ErrorDescription) VALUES (" & ErrNumber & ", '" & ErrDescription & "')"
Currentdb.Excecute strSQL, dbFailOnError
End Function
叫:
If DLook("Column2", "Table1", "Column1 = " & ID) = 0 Then
'Do stuff
End If
If DLook("Column2", "Table1") = 0 Then
'Do other stuff
End If