如何从VBA函数返回结果


Answers:


429

对于非对象返回类型,必须将值分配给函数的名称,如下所示:

Public Function test() As Integer
    test = 1
End Function

用法示例:

Dim i As Integer
i = test()

如果函数返回对象类型,则必须使用如下Set关键字:

Public Function testRange() As Range
    Set testRange = Range("A1")
End Function

用法示例:

Dim r As Range
Set r = testRange()

请注意,将返回值分配给函数名称不会终止函数的执行。如果要退出该功能,则需要明确说出Exit Function。例如:

Function test(ByVal justReturnOne As Boolean) As Integer
    If justReturnOne Then
        test = 1
        Exit Function
    End If
    'more code...
    test = 2
End Function

文档:http : //msdn.microsoft.com/zh-cn/library/office/gg264233%28v=office.14%29.aspx


32
为了完整起见,应该注意的是,当您返回一个对象(例如a Range)时,您需要Set像在常规方法中设置对象变量一样使用。因此,例如,如果“ test”是一个返回Range的函数,则return语句将如下所示set test = Range("A1")
杰·卡尔

为什么是@JayCarr?
PsychoData

4
@PsychoData-仅仅因为这是您通常设置对象变量的方式,否则就set可能导致问题。我在没有它的情况下遇到了问题,但是如果使用,set我就不会:)。
杰伊·卡尔

1
我认为还值得一提的是,与从另一个VBA函数或Sub调用函数相比,从电子表格调用函数的行为有所不同。
道格·詹金斯

2
在VBA中调用该函数时,它将返回一个范围对象,但是从工作表中调用时,该函数将仅返回该值,因此set test = Range("A1")它完全等效于test = Range("A1").Value,其中“ test”被定义为Variant,而不是Range。
道格·詹金斯

86

VBA函数将函数名称本身视为一种变量。因此,不用使用“ return”语句,您只需说:

test = 1

但是请注意,这不会超出该功能。该语句之后的任何代码也将被执行。因此,您可以有许多赋值语句,它们为分配不同的值test,而到达函数末尾的值将是返回的值。


实际上,您使用其他信息可以更清楚地回答该问题(这可能会导致从VBA新手到另一个问题)。保持良好的工作状态
阿达沙(Adarsha)2010年

抱歉,您似乎刚刚回答了与我最初回答的内容相同的问题,只是添加了一个事实,那就是它不会脱离功能。这是一个很好的补充,我只是认为它更适合作为评论。我不确定适当的礼节是什么,我想为此拒绝投票是很不礼貌的,因为这是一个很好的答案,但我不会撤销它。

41

仅将返回值设置为函数名称仍然与Java(或其他)语句不完全相同return,因为在Java中,return退出函数的方式如下:

public int test(int x) {
    if (x == 1) {
        return 1; // exits immediately
    }

    // still here? return 0 as default.
    return 0;
}

在VB中,如果未在函数末尾设置返回值,则精确等效项需要两行。因此,在VB中,确切的推论如下所示:

Public Function test(ByVal x As Integer) As Integer
    If x = 1 Then
        test = 1 ' does not exit immediately. You must manually terminate...
        Exit Function ' to exit
    End If

    ' Still here? return 0 as default.
    test = 0
    ' no need for an Exit Function because we're about to exit anyway.
End Function 

既然是这种情况,也很高兴知道您可以像方法中的其他变量一样使用return变量。像这样:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test <> 1 Then ' Test the currently set return value
        test = 0 ' Reset the return value to a *new* value
    End If

End Function 

或者,一个关于返回变量如何工作的极端示例(但不一定是关于您应该如何实际编码的一个很好的示例)—一个使您彻夜难眠的示例:

Public Function test(ByVal x As Integer) As Integer

    test = x ' <-- set the return value

    If test > 0 Then

        ' RECURSIVE CALL...WITH THE RETURN VALUE AS AN ARGUMENT,
        ' AND THE RESULT RESETTING THE RETURN VALUE.
        test = test(test - 1)

    End If

End Function

2
“很高兴知道您可以像使用该方法中的其他任何变量一样使用return变量” 基本上是正确的-但例如,如果return类型为Variant并且您的目标是返回数组,则类似的操作ReDim test(1 to 100)将触发错误。而且,即使它可以治疗的基本类型像Integers这样说,这被认为是有点unidiomatic。它使代码更难阅读。VBA程序员扫描分配给函数名称的行,以了解函数的作用。将函数名称用作常规变量会不必要地掩盖这一点。
John Coleman

@JohnColeman,完全同意这两点。最后一个例子绝不应成为推荐的方法之一。但是,主题问题是关于如何返回变量的,因此,这只是试图全面解释VB的返回结果以及其扩展方式。当然,最后一种情况不是建议。(我当然不仅仅将其编码为示例。)因此,您的观点是正确的,并且是很好的补充。谢谢。
LimaNightHawk '16

对短小的功能是有用的,是值得任何VBA编程人员应该知道的,所以我没有问题,你提到这一点。我只是认为应该包含警告。
John Coleman

感谢解释如何Exit Functionreturn
Austin D

@JohnColeman,显然,您不能ReDim test(1 to 100)仅仅因为'test'未声明为数组而触发错误!完全没有其他原因!您不能将函数声明为数组。将其声明为Variant,然后在此函数内部构建输出数组(可以是动态数组或静态数组)test,然后将此数组赋值(“ =”)test作为返回值。为了像ReDim它一样进行进一步的操作,您需要将返回的值分配给变量,例如Dim x as Variantand call x = test,之后x就是您test要做的!
基因

-6

下面的代码将返回值存储到变量中retVal,然后MsgBox可用于显示该值:

Dim retVal As Integer
retVal = test()
Msgbox retVal
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.