339

How do I return a result from a function?

For example:

Public Function test() As Integer
    return 1
End Function

This gives a compile error.

How do I make this function return an integer?

Machavity
  • 30,841
  • 27
  • 92
  • 100
Mike
  • 58,961
  • 76
  • 175
  • 221

3 Answers3

514

For non-object return types, you have to assign the value to the name of your function, like this:

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

Example usage:

Dim i As Integer
i = test()

If the function returns an Object type, then you must use the Set keyword like this:

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

Example usage:

Dim r As Range
Set r = testRange()

Note that assigning a return value to the function name does not terminate the execution of your function. If you want to exit the function, then you need to explicitly say Exit Function. For example:

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

Documentation: Function Statement

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
Dan
  • 9,935
  • 15
  • 56
  • 66
  • 37
    For completeness it should be noted that when you are returning an object (like a `Range` for example), you need to use `Set` just like you would if setting an object variable in a regular method. So if, for example, "test" were a function that returned a Range the return statement would look like this `set test = Range("A1")`. – Jay Carr Mar 21 '13 at 15:23
  • Why is that @JayCarr? – PsychoData Feb 11 '14 at 14:07
  • 5
    @PsychoData - Simply because that's how you set an object variable in general, and doing it without `set` can lead to problems. I've had issues doing it without, but if I use `set` I don't :). – Jay Carr Feb 11 '14 at 14:36
  • Maybe it's because if you just give a variable a value like a string or an integer aso so you are just adding the value to the variable. Instead for an object this is containing a lot more information and if for example you give it a range then that range is renamed after your variable in your code. So rather than adding the value to the variable, you're giving the range of values a new name. Could this be right? – Kathara Jan 19 '16 at 13:34
  • `Exit Sub` for exiting a Sub. – Roland Oct 03 '17 at 06:05
  • 1
    I think it is also worth mentioning that the behaviour of the function differs when you call it from a spreadsheet, compared with calling it from another VBA function or Sub. – Doug Jenkins Sep 13 '18 at 23:08
  • 5
    When called within VBA the function will return a range object, but when called from a worksheet it will return just the value, so `set test = Range("A1")` is exactly equivalent to `test = Range("A1").Value`, where "test" is defined as a Variant, rather than a Range. – Doug Jenkins Sep 13 '18 at 23:18
89

VBA functions treat the function name itself as a sort of variable. So instead of using a "return" statement, you would just say:

test = 1

Notice, though, that this does not break out of the function. Any code after this statement will also be executed. Thus, you can have many assignment statements that assign different values to test, and whatever the value is when you reach the end of the function will be the value returned.

Jean-François Corbett
  • 37,420
  • 30
  • 139
  • 188
froadie
  • 79,995
  • 75
  • 166
  • 235
  • 2
    Actually you answered the question more clearly with extra information (which could potentialy lead to another question from new to VBA guy). Keep up the good work – Adarsha May 06 '10 at 14:39
  • Sorry, It seemed like you just answered the same thing as my answer, which I had first, but just adding the fact that it doesn't break out of the function. It is a nice addition, I just thought it'd be more appropriate as a comment. I'm not sure what the proper etiquette is, I guess it was a bit rude to downvote for just that, because it is a good answer, but it won't let me undo it. – Dan May 06 '10 at 15:20
49

Just setting the return value to the function name is still not exactly the same as the Java (or other) return statement, because in java, return exits the function, like this:

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

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

In VB, the exact equivalent takes two lines if you are not setting the return value at the end of your function. So, in VB the exact corollary would look like this:

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 

Since this is the case, it's also nice to know that you can use the return variable like any other variable in the method. Like this:

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 

Or, the extreme example of how the return variable works (but not necessarily a good example of how you should actually code)—the one that will keep you up at night:

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
Greedo
  • 4,967
  • 2
  • 30
  • 78
LimaNightHawk
  • 6,613
  • 3
  • 41
  • 60
  • 2
    "it's also nice to know that you can use the return variable like any other variable in the method" is *mostly* true -- but e.g. if the return type is `Variant` and your goal is to return an array then something like `ReDim test(1 to 100)` will trigger an error. Also, even though it *is* possible to treat basic type like `Integers` like that it is considered somewhat unidiomatic. It makes the code harder to read. VBA programmers scan for lines which assign to the function name to understand what a function does. Using the function name as a regular variable needlessly obscures this. – John Coleman Apr 04 '16 at 13:49
  • @JohnColeman, totally agree on both points. By no means should the last example be one of recommended methodology. But, the topic question is regarding How to return a variable, and so this is just an attempt at a full explanation of VB's return result, and by extension how they work. Certainly the last case is not a recommendation. (I certainly would not code that as more than an example.) So, your points are well taken, and good additions. Thank you. – LimaNightHawk Apr 04 '16 at 15:00
  • It *is* useful for smallish functions, and is something that any VBA programmer should know about, so I had no problem with you mentioning it. I just thought that a warning should be included. – John Coleman Apr 04 '16 at 15:10
  • Thanks explaining how `Exit Function` relates to `return` – Austin Jul 09 '16 at 20:01
  • @JohnColeman, Obviously, you cannot `ReDim test(1 to 100)` without triggering an error simply because 'test' is not declared as an array! and for no other reason at all! You cannot declare a function as an array. Declare it as a `Variant`, then just build your output array (it can be Dynamic or Static) inside this function `test` and then assign ("=") this array to `test` as a return value. To further manipulate, like `ReDim`ing it, you need to assign the returned value to a variable, e.g. `Dim x as Variant` and call `x = test`, after which `x` is what you made the `test` to be! –  Dec 31 '18 at 16:47
  • 1
    @Gene I don't follow. It isn't necessary to declare a variable as an array to `ReDim` it. `Dim test As Variant` followed by `ReDim test(1 to 100)` is unproblematic. That you *can't* do this with the name of a variant function in the body of the function shows that it isn't true that you can use the return variable like any other variable in the body of the function, which is exactly the point that I was making. By the way, your use of exclamation marks seems over-the-top. In an internet context it seems vaguely troll-like, although there is nothing troll-like about your comment. – John Coleman Dec 31 '18 at 17:20
  • @John Coleman; The `Dim test As Variant` followed by `ReDim test(1 to 100)` is unproblematic because VBA re-interpretes the redim request as "aha, you mean that `test` Variant should be an 'array' sub-type". The function itself cannot be declared as an array, VBA will not allow it (does not have a way of doing it). You need to use a `Variant` and "stuff" it on return with an array if that's what you want the function to return. It will be a Variant array, not a String array, or a Long array, etc. –  Dec 31 '18 at 19:05
  • 1
    @Gene you are right only by accident. Your reasons are wrong. – Excel Hero Mar 18 '20 at 10:11
  • @Excel Hero Hurrah! You know something some of us (namely, me) do not know or understand. It is great, but could you, like... explain what it is and, hopefully, why? Thank you in advance. –  Mar 18 '20 at 20:56