引发一个函数返回的错误的正确语法

huangapple go评论84阅读模式
英文:

Proper syntax for raising an error that a function returns

问题

这个函数要么返回一个错误号,要么在正常运行时返回0。

Public Function DeleteTable(tblName As String) As Long
    On Error Resume Next
    DoCmd.DeleteObject acTable, tblName
    DeleteTable = Err
End Function

这个子程序运行正常...

Private Sub cmdRefresh_Click()
    Dim ReturnedErr As Long
    ReturnedErr = DeleteTable("tblFoo")
    If ReturnedErr Then Err.Raise ReturnedErr

    '做一些其他事情
End Sub

但是否有一种方式可以编写它,而不必将返回的值传递给一个新变量?这样似乎有点笨拙。是否有可能像这样实现?

Private Sub cmdRefresh_Click()
    Err.Raise DeleteTable("tblFoo")
    '(不起作用,因为 err.raise 0... 会引发一个错误)

    '做一些其他事情
End Sub
英文:

This function returns either an error number, or 0 if it ran smoothly.

Public Function DeleteTable(tblName As String) As Long
    On Error Resume Next
    DoCmd.DeleteObject acTable, tblName
    DeleteTable = Err
End Function

This sub works fine...

Private Sub cmdRefresh_Click()
    Dim ReturnedErr As Long
    ReturnedErr = DeleteTable("tblFoo")
    If ReturnedErr Then Err.Raise ReturnedErr

    'do stuff
End Sub

But is there a way to write it where I don't have to pass the returned value into a new variable? Seems clunky. Is something like this possible?

Private Sub cmdRefresh_Click()
    err.raise DeleteTable("tblFoo")
    '(doesn't work because an err.raise of 0 ... raises an error)

    'do stuff
End Sub

答案1

得分: 2

Option Explicit

Public Sub DeleteTable(tblName As String) ' 一个子程序就足够了
    On Error Resume Next
    Err.Raise 1 ' <- 仅用于测试:任何错误,除了0
End Sub

Public Sub test()
    DeleteTable ("tblFoo") ' <- 不返回DeleteTable中的err.number
    If Err.Number Then ' <- 上一个语句的错误将会保留
       'Err.Raise Err.Number ' <- 您现在可以引发错误,它总是一个有效的错误编号
       '或者显示比MS更好的消息:
       MsgBox "错误(" & Err.Number & ") " & Err.Description & vbCrLf & vbCrLf & "在 '" & Mid(Application.CodeDb.Name, 1 + InstrRev(Application.CodeDb.Name, "\")) & "', 函数 'DeleteTable'"
    Else
       '做一些操作
    End If
End Sub
英文:
Option Explicit

Public Sub DeleteTable(tblName As String) &#39; a Sub is just fine
    On Error Resume Next
    Err.Raise 1 &#39; &lt;- just for testing: any error, other than 0
End Sub
Public Sub test()
    DeleteTable (&quot;tblFoo&quot;) &#39; &lt;- don&#39;t return the err.number in DeleteTable
    If Err.Number Then     &#39; &lt;- the error of the last statement will be preserved
       &#39;Err.Raise Err.Number &#39; &lt;- You can raise the error now, it is always a valid error number here
       &#39;Or show a better message than MS does:
       MsgBox &quot;Error(&quot; &amp; Err.Number &amp; &quot;) &quot; &amp; Err.Description &amp; vbCrLf &amp; vbCrLf &amp; &quot;in &#39;&quot; &amp; Mid(Application.CodeDb.Name,1+InstrRev(Application.CodeDb.Name,&quot;\&quot;)) &amp; &quot;&#39;, Function &#39;DeleteTable&#39;&quot;
    Else
       &#39;do stuff
    End If
End Sub

答案2

得分: 0

在这种情况下,使用 Rubberduck 博客中针对 VBA 描述的 Try 函数可能会很有帮助。

https://rubberduckvba.blog/2019/05/09/pattern-tryparse/

一个 Try 函数返回一个布尔值(true/False),指示操作是否成功。期望的值和错误代码通过 ByRef 参数返回。

Try 函数应该只包含尝试操作的代码,然后返回操作的结果。


' DeleteTable 方法变为
Public Function TryDeleteTable(byref tblName As String, byref outErrNum as long) As Boolean
    On Error Resume Next
    DoCmd.DeleteObject acTable, tblName
    outErrnum = err.number
    DeleteTable = Err.number = 0
    on error goto 0
End Function

' 并且如下使用

Private Sub cmdRefresh_Click()
    Dim ReturnedErr As Long
    if Not DeleteTable("tblFoo",ReturnedErr) then
       ' 处理错误
       ' 例如 Err.Raise ReturnedErr
    end if
    ' 继续正常流程

End Sub

如果你还没有安装免费且非常棒的 Rubberduck 插件,现在应该去安装。它是一个非常非常实用的插件。

英文:

In such situations it can be helpful to use a Try function as described for VBA in a Rubberduck blog.

https://rubberduckvba.blog/2019/05/09/pattern-tryparse/

A try function returns a boolean (true/False) to indicate if the operation was a success or not. The desired value and error numbers are returned through ByRef parameters.

The try function should contain only the code that attempts an operation then returns the result of the operation


&#39; The DeleteTable method becomes
Public Function TryDeleteTable(byref tblName As String, byref outErrNum as long) As Boolean
    On Error Resume Next
    DoCmd.DeleteObject acTable, tblName
    outErrnum = err.number
    DeleteTable = Err.number = 0
    on error goto 0
End Function

&#39; and is used as follows

Private Sub cmdRefresh_Click()
    Dim ReturnedErr As Long
    if Not DeleteTable(&quot;tblFoo&quot;,ReturnedErr) then
       &#39;deal with error
       &#39;e.g. Err.Raise ReturnedErr
    end if
    &#39; continue on the happy path

End Sub

If you haven't already installed the free and fantastic Rubberduck add in you should do so now. Its a really really useful addin.

huangapple
  • 本文由 发表于 2023年7月11日 04:58:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76657310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定