【问题标题】:How to return a result from a VBA function如何从 VBA 函数返回结果
【发布时间】:2018-02-21 11:26:41
【问题描述】:

如何从函数返回结果?

例如:

Public Function test() As Integer
    return 1
End Function

这会导致编译错误。

如何让这个函数返回一个整数?

【问题讨论】:

标签: excel vba function return return-value


【解决方案1】:

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

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

文档:Function Statement

【讨论】:

  • 为了完整起见,应该注意的是,当您返回一个对象时(例如Range),您需要使用Set,就像在常规中设置对象变量一样方法。因此,例如,如果“test”是一个返回 Range 的函数,则 return 语句将如下所示 set test = Range("A1")
  • 为什么是@JayCarr?
  • @PsychoData - 仅仅因为这就是您设置对象变量的一般方式,并且在没有set 的情况下执行此操作可能会导致问题。我没有这样做有问题,但如果我使用set,我不会:)。
  • 我认为还值得一提的是,与从另一个 VBA 函数或 Sub 调用相比,从电子表格调用函数时,函数的行为有所不同。
  • 当在 VBA 中调用时,该函数将返回一个范围对象,但当从工作表调用时,它将只返回值,因此set test = Range("A1") 完全等同于test = Range("A1").Value,其中“test”是定义为 Variant,而不是 Range。
【解决方案2】:

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

test = 1

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

【讨论】:

  • 实际上你用额外的信息更清楚地回答了这个问题(这可能会导致 VBA 新手的另一个问题)。继续努力
  • 对不起,您的回答似乎与我的回答相同,但只是添加了它不会超出功能的事实。这是一个很好的补充,我只是认为它更适合作为评论。我不确定正确的礼仪是什么,我想为此投反对票有点粗鲁,因为这是一个很好的答案,但它不会让我撤消它。
【解决方案3】:

只是给函数名设置返回值还是不完全和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 

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

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

【讨论】:

  • “很高兴知道您可以像方法中的任何其他变量一样使用返回变量”大部分是正确的——但例如如果返回类型是 Variant 并且您的目标是返回一个数组,那么像 ReDim test(1 to 100) 这样的东西会触发一个错误。此外,即使 可以处理像 Integers 这样的基本类型,但它被认为有点单调。它使代码更难阅读。 VBA 程序员扫描分配给函数名称的行以了解函数的作用。将函数名用作常规变量会不必要地掩盖这一点。
  • @JohnColeman,在这两点上完全同意。最后一个例子绝不应该是推荐的方法之一。但是,主题问题是关于如何返回变量,因此这只是尝试对 VB 的返回结果进行全面解释,并扩展它们是如何工作的。当然,最后一种情况不是建议。 (我当然不会将其编码为一个示例。)因此,您的观点得到了很好的理解,并且是很好的补充。谢谢。
  • 对小函数很有用,是任何VBA程序员都应该知道的,所以我对你提到它没有问题。我只是认为应该包括一个警告。
  • @Gene 我不关注。没有必要将变量声明为ReDim 的数组。 Dim test As Variant 后跟 ReDim test(1 to 100) 没有问题。您不能在函数体中使用变体函数的名称来执行此操作,这表明您不能像使用函数体中的任何其他变量一样使用返回变量功能,这正是我要提出的观点。顺便说一句,您对感叹号的使用似乎过分了。在互联网环境中,它似乎有点像巨魔,尽管您的评论与巨魔没有任何相似之处。
  • @Gene 你是对的只是偶然。你的理由是错误的。
【解决方案4】:

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

Dim retVal As Integer
retVal = test()
Msgbox retVal

【讨论】:

    猜你喜欢
    • 2012-12-19
    • 1970-01-01
    • 2017-01-23
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    相关资源
    最近更新 更多