如何从 VBA 函数返回结果

How to return a result from a VBA function

提问人:Mike 提问时间:5/6/2010 最后编辑:MachavityMike 更新时间:7/6/2021 访问量:1068502

问:

如何从函数返回结果?

例如:

Public Function test() As Integer
    return 1
End Function

这会产生编译错误。

如何使此函数返回整数?

Excel VBA 函数 返回值

评论

12赞 Jean-François Corbett 9/15/2014
文档:msdn.microsoft.com/en-us/library/office/...

答:

516赞 Dan 5/6/2010 #1

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

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

用法示例:

Dim i As Integer
i = test()

如果函数返回 Object 类型,则必须使用如下关键字: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

文档:函数语句

评论

37赞 Jae Carr 3/21/2013
为了完整起见,应该注意的是,当您返回一个对象(例如一个)时,您需要像在常规方法中设置对象变量一样使用。因此,例如,如果“test”是一个返回 Range 的函数,则 return 语句将如下所示。RangeSetset test = Range("A1")
0赞 PsychoData 2/11/2014
为什么会这样@JayCarr?
5赞 Jae Carr 2/11/2014
@PsychoData - 仅仅因为这是你通常设置对象变量的方式,如果不这样做可能会导致问题。我在没有它的情况下遇到了问题,但如果我使用,我不会:)。setset
1赞 Doug Jenkins 9/14/2018
我认为还值得一提的是,当您从电子表格中调用它时,该函数的行为与从另一个 VBA 函数或 Sub 调用它时不同。
5赞 Doug Jenkins 9/14/2018
在 VBA 中调用时,该函数将返回一个 range 对象,但当从工作表调用时,它将只返回值,因此完全等效于 ,其中“test”定义为 Variant,而不是 Range。set test = Range("A1")test = Range("A1").Value
89赞 froadie 5/6/2010 #2

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

test = 1

但请注意,这不会超出函数。此语句之后的任何代码也将被执行。因此,您可以有许多赋值语句,这些赋值语句将不同的值赋值给 ,并且当您到达函数末尾时,无论该值是什么,都将是返回的值。test

评论

2赞 Adarsha 5/6/2010
实际上,您使用额外的信息更清楚地回答了这个问题(这可能会导致从新手到VBA人员的另一个问题)。保持良好的工作
0赞 Dan 5/6/2010
对不起,您似乎刚刚回答了与我的答案相同的事情,这是我首先回答的,但只是添加了它不会脱离功能的事实。这是一个很好的补充,我只是认为它作为评论会更合适。我不确定正确的礼仪是什么,我想投反对票有点不礼貌,因为这是一个很好的答案,但它不会让我撤消它。
49赞 LimaNightHawk 6/12/2014 #3

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

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 

既然是这种情况,那么很高兴知道您可以像使用方法中的任何其他变量一样使用返回变量。喜欢这个:

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赞 John Coleman 4/4/2016
“很高兴知道您可以像使用方法中的任何其他变量一样使用返回变量”大是正确的 - 但是,例如,如果返回类型是并且您的目标是返回数组,那么类似的东西将触发错误。此外,即使可以这样对待基本类型,它也被认为是某种单一的。它使代码更难阅读。VBA 程序员扫描分配给函数名称的行,以了解函数的作用。使用函数名称作为常规变量会不必要地掩盖这一点。VariantReDim test(1 to 100)Integers
0赞 LimaNightHawk 4/4/2016
@JohnColeman,完全同意这两点。最后一个例子绝不应该是推荐的方法之一。但是,主题问题是关于如何返回变量,因此这只是对 VB 返回结果以及它们如何工作的尝试。当然,最后一种情况不是建议。(我当然不会把它当作一个例子。所以,你的观点很好,而且很好。谢谢。
0赞 John Coleman 4/4/2016
它对小型函数很有用,并且是任何 VBA 程序员都应该知道的东西,所以我对你提到它没有问题。我只是认为应该包括一个警告。
1赞 John Coleman 1/1/2019
@Gene我不关注。没有必要将变量声明为数组。 其次是没有问题的。你不能在函数主体中使用变体函数的名称来做到这一点,这表明你可以像函数主体中的任何其他变量一样使用返回变量,这正是我要表达的观点。顺便说一句,你对感叹号的使用似乎有些过分了。在互联网背景下,它似乎有点像巨魔,尽管您的评论没有任何巨魔。ReDimDim test As VariantReDim test(1 to 100)
1赞 Excel Hero 3/18/2020
@Gene你是对的只是偶然的。你的理由错了。