Skip to main content

Passing variables to functions and subs

One of the Canadian trainers sent me these two scripts.  They look pretty much alike but the first one references the functions and subs using function x while the second uses function (x) so the only difference is that the variable being passed is in () in one of the script.  Well if you try and run it you get the expect results with the first test in that the varaible gets incremented but if you run the second script the variable keeps the value 1 all along.  Well it turns out that this is the way that microsoft wanted it to work, you can see their rational at http://msdn.microsoft.com/en-us/library/ddck1z30(v=vs.71).aspx It seems that when you place the variable in () it views it as an expression and not a variable and per the web page expressions are never modified.  So this is useful information if you are writing a script and passing variables and wondering why it is not working properly.  Thanks Jeff for this tip.

'  Name:  testing scope3
'  Purpose: Determine exactly how the scope of Subs and Functions can affect the value of the calling parameters
'
'  Result:  Both Subs and Functions increase the original counter value where ByRef is used

Sub Main
 Dim x As Integer  ' don't declare variable
 x = 1
 MsgBox "default, x=" & x
 
 sbByRef2 x
 MsgBox "subByRef2=" & x 
 
 sbByVal2 x
 MsgBox "subByVal2=" & x 
 
 funcByRef2 x  
 MsgBox "funcByRef2=" & x 
 
 funcByVal2 x  
 MsgBox "funcByVal2=" & x
 
End Sub

Sub sbByRef2 (x As Integer)
 x = x + 1
End Sub

Sub sbByVal2 (ByVal x As Integer)
 x = x + 1
End Sub

Function funcByRef2 (x As Integer)
 x = x + 1
End Function

Function funcByVal2 (ByVal x As Integer)
 x = x + 1
End Function

'  Name:  testing scope4
'  Purpose: Determine exactly how the scope of Subs and Functions can affect the value of the calling parameters
'
'  Result:  This code, while it looks very similar, changes the behaviour.  By having parentheses during the call, (x) becomes
'  an expression, which makes the parameter a "non-variable element", which means its value will never impact the calling
'  variable.  See here for the explanation: http://msdn.microsoft.com/en-us/library/ddck1z30(v=vs.71).aspx

Sub Main
 Dim x As Integer  ' don't declare variable
 x = 1
 MsgBox "default, x=" & x
 
 sbByRef2(x) ' << note the parentheses
 MsgBox "subByRef2=" & x ' * in a Sub, with variables different, x is not impacted
 
 sbByVal2(x)
 MsgBox "subByVal2=" & x ' * in a Sub, with variables different ByVal, x is not impacted
 
 funcByRef2(x)  ' ** in a Function, reusing "x", this one increases main x by +1
 MsgBox "funcByRef2=" & x ' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
 funcByVal2(x)  ' ** in a Function, reusing "x" with ByVal, x is not impacted
 MsgBox "funcByVal2=" & x
 
End Sub

Sub sbByRef2 (x As Integer)
 x = x + 1
End Sub

Sub sbByVal2 (ByVal x As Integer)
 x = x + 1
End Sub

Function funcByRef2 (x As Integer)
 x = x + 1
End Function

Function funcByVal2 (ByVal x As Integer)
 x = x + 1
End Function