使用And而不是分支会导致#REF错误

时间:2018-11-20 19:42:06

标签: vba

我在VBA中编写了一个非常简单的函数,该函数使用3个参数通过一个表达式来计算某个值。问题是,如果参数之一不是数字或小于或等于0,则该函数还必须调出特定的消息框。

因此,我第一次尝试使用此代码

Function refraction(a, b, c)

If IsNumeric(a) And IsNumeric(b) And IsNumeric(c) Then
    If (a > 0) And (b > 0) And (c > 0) Then
        refraction = (a ^ 2 - 1) * b / c / (a ^ 2 + 2)
    Else
    MsgBox "Range!"
    Exit Function
    End If
Else
MsgBox "Number!"
Exit Function
End If

End Function

无论参数是什么,即使它们都是数字且为正数,它都会返回#REF错误。

所以我尝试了一种更简单的方法

Function refrakcja(a, b, c)

If IsNumeric(a) Then
    If IsNumeric(b) Then
        If IsNumeric(c) Then
            If a > 0 Then
                If b > 0 Then
                    If c > 0 Then
                        refrakcja = (a ^ 2 - 1) * b / c / (a ^ 2 + 2)
                    Else
                    MsgBox "Range!"
                    Exit Function
                    End If
                Else
                MsgBox "Range!"
                Exit Function
                End If
            Else
            MsgBox "Range!"
            Exit Function
            End If
        Else
        MsgBox "Number!"
        Exit Function
        End If
    Else
    MsgBox "Number"
    Exit Function
    End If
Else
MsgBox "Number!"
Exit Function
End If

End Function

那像魅力一样工作。那我在做什么错了?

2 个答案:

答案 0 :(得分:3)

如果所有数字均大于0,则至少需要Exit Function。在下面的示例中,我返回一个Variant。您不需要其他Exit Functions。您可以让程序运行到最后,并返回您认为合适的值。您还可以考虑在函数签名中强制使用类型,然后添加错误处理。

Option Explicit

Public Sub test()

    Debug.Print refraction(12, -4, 3)

End Sub
Public Function refraction(ByVal a As Variant, ByVal b As Variant, ByVal c As Variant) As Variant
    Dim ref2  As Long
    If IsNumeric(a) And IsNumeric(b) And IsNumeric(c) Then
        If (a > 0) And (b > 0) And (c > 0) Then
            ref2 = (a ^ 2 - 1) * b / c / (a ^ 2 + 2)
            refraction = ref2
            Exit Function
        Else
            MsgBox "Range!"
        End If
    Else
        MsgBox "Number!"
    End If
    refraction = "Invalid values passed"
End Function

答案 1 :(得分:2)

将结果设置为失败值作为函数的第一步,这意味着您将始终返回有效值。逆向逻辑以尽早结束功能可以使代码更具可读性。

Function refraction(ByVal a As Double, ByVal b As Double, ByVal c As Double) As Variant

    refraction = vbEmpty

    If Not (IsNumeric(a) And IsNumeric(b) And IsNumeric(c)) Then
        MsgBox "A parameter was not numeric"
        Exit Function
    End If

    If Not ((a > 0) And (b > 0) And (c > 0)) Then
        MsgBox "A parameter was negative"
        Exit Function
    End If

    refraction = (a ^ 2 - 1) * b / c / (a ^ 2 + 2)

End Function