I am trying to write a simple function where, based on the parameter I am passing, I need to return a string value. I am getting error Compile error: Syntax error.
Public Function getServer(env As String) As String
Dim serverName As String
Select Case env
Case "DEV"
serverName = "abc"
Return serverName;
Case "TEST"
serverName = "def"
Return serverName;
Case "Prod"
serverName = "xyz"
Return serverName;
End Select
End Function
VBA doesn't use Return to exit a function early, or to specify the returned value of the function. In VBA, you specify early exit using Exit Function; and in order to return a value or object from a function, you have to assign / set the name of the function to the value / object you want to return:
Public Function getServer(env As String) As String
Select Case env
Case "DEV"
getServer = "abc"
Case "TEST"
getServer = "def"
Case "Prod"
getServer = "xyz"
End Select
End Function
In VBA the Return statement (which does exist) serves an entirely different purpose; it's used in conjunction with the legacy GoSub statement, to return from a subprocedure jump:
bar = 42
GoSub Foo
Exit Sub
Foo:
Debug.Print bar
Return
This type of construct is present in the language to support earlier versions/dialects of BASIC, and shouldn't be seen in modern VBA code.
Functions and Property Get procedures return their return value by assigning to the procedure's identifier:
getServer = "abc"
Note that the procedure's identifier is essentially a local variable, and thus the assignment doesn't return. Use Exit Function statements to bail out.
Also, {NEWLINE} is the end-of-instruction marker in VBA, not ; semicolon ;-)
The semicolon is used in VBA to control the behavior of string-printing, e.g. Debug.Print and Write# statements.
Sub test()
Debug.Print 1; 2; 3;
Debug.Print 4; 5; 6; ' prints on the same line as the previous statement
End Sub
Whereas this would output on 2 separate lines:
Sub test()
Debug.Print 1; 2; 3
Debug.Print 4; 5; 6 ' prints on the next line
End Sub
Related
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?
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
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.
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
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?
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
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.
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
I want to create a function where I use one parameter so the function returns another value. In this case I want to insert "links" in a function and then the function should give me back "Left" (Im need a of 'translations' so therefore I use case of if statements.
I have the following function
Public Function newParameter(aParameter) As Integer
Select Case aParameter
Case Is = "Links"
aParameter = "ppAlignLeft"
End Select
End Function
Sub finalFunction()
Dim newParameter As String
newParameter = newParameter(Links)
MsgBox (newParameter)
End Sub
This however gives me a compile error that a matrix is required. Any thoughts on how I can get this working?
You're passing the argument ByRef and change it's value. You dont need a function for this. Functions retun values.
Since you are using a Function though, why dont you have the Function return the value you want?
Public Function newParameter(ByVal aParameter As String) As String
Select Case aParameter
Case "Links":
newParameter = "ppAlignLeft"
Case "A":
newParameter = "You passed A"
Case Else:
newParameter = "No match"
End Select
End Function
Sub finalFunction()
Dim newParameter1 As String
newParameter1 = newParameter("Links") 'This reads 'ppAlignLeft'
MsgBox newParameter1
End Sub
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?
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
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.
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
I want a list of possible values to show up when I call a function func1. I found a way to achieve this in VBA via ENUM, but that doesn't work in a worksheet. So I've created a function e that will convert certain strings into the right enum value. Unfortunately, I can't find a way to call this function func1 with either a string or the enum value without getting an error or losing functionality. Here's what I've got so far:
Enum eLanguages
evEnglish = 2
evItalian = 3
'and so on
End Enum
Function e(vString)
Select Case vString
Case "english", "eng", "en", "e"
e = evEnglish
Case "italian", "italien", "it", "i"
e = evItalian
Case Else
e = vString '(= will keep the value if it's already a number)
End Select
End Function
Option 1: Shows the list of possible values when typing in VBA, but won't work for string inputs
Function func1(var As eLanguages)
func1 = e(var)
End Function
Sub test1()
MsgBox func1(evEnglish) 'Will result in 2 (through the enum and the e function)
MsgBox func1("e") 'Type 13 error
End Sub
Option 2: Gives the right result but I don't get the list of possible values within VBA
Function func2(var)
func2 = e(var)
End Function
Sub test2()
MsgBox func2(evEnglish) 'Will result in 2 (through the enum and the e function)
MsgBox func2("e") 'Will result in 2 (through the e function)
End Sub
Note: Calling either of the two functions like this will give the right result, but obviously I'm not keen on having to write e() everytime I call the function:
MsgBox func1(e("e"))
So do you have any suggestions on how to ignore the Type 13 error or how to include an "any string allowed" option in the ENUM declaration?
Thanks in advance.
#CinyMeister 's idea is interesting. A slight variation -- make both arguments optional and use if - then - else, together with the IsMissing function to merge the two arguments back into one: Function func3(Optional x As eLanguages, Optional y As String)
Dim var As Variant
If IsMissing(x) Then
var = y
Else
var = x
End If
func3 = e(var)
End Function
Sub test()
MsgBox func3(evEnglish)
MsgBox func3(, "it")
End Sub
Even with a large number of parameters, this sort of thing will work -- when you invoke the function in the VBA editor you can tab through the options by repeatedly pressing the comma key. Parameters that are given by enumerations will evoke intellisense drop-downs. Other parameters will hopefully have descriptive names.
I just had another idea, but I don't think it would work as a superelegant solution either.
I could have 2 functions, one for Excel, one for VBA. Like that:
Function funcV(var As eLanguages)
funcV = SOMETHING
End Function
Function funcE(var)
funcE= funcV(e(var)) '(which is "SOMETHING")
End Function
The question is whether I would remember which of my many functions have a sister function. There's no way to capture the Type 13 error as an "on error" event and redirect automatically, is there?