Functions in VBA at least can only ever return 1 thing. That thing could contain multiple values, but it's still 1 package.
I would like to create a Sub/Function which has an effect on the values of more than 1 variable. As far as I know, these are the 3 ways of doing that:
1. Declare the variables outside the Caller sub
Private val1 As Long, val2 As Long
Sub Caller()
val1 = 1
val2 = 2
valueChanger
Debug.Print val1 + val2 'Prints 5
End Sub
Sub valueChanger() 'no need to pass any values, but could pass both byVal
val1 = val1 + 1
val2 = val2 + 1
End Sub
2. Pass byRef
Sub Caller()
Dim val1 As Long, val2 As Long
val1 = 1
val2 = 2
valueChanger val1, val2
Debug.Print val1 + val2 'Prints 5
End Sub
Sub valueChanger(ByRef value1 As Long, ByRef value2 As Long)
value1 = value1 + 1
value2 = value2 + 1
End Sub
3. Return both in a single "packet"
Sub Caller()
Dim val1 As Long, val2 As Long, results() As Long
val1 = 1
val2 = 2
results = valueChanger(val1, val2)
Debug.Print results(1) + results(2) 'Prints 5
End Sub
Function valueChanger(ByVal value1 As Long, ByVal value2 As Long) As Long() 'return an array, could equally return a collection or even a string
Dim resultVals(1 To 2) As Long
resultVals(1) = value1 + 1
resultVals(2) = value2 + 1
valueChanger = resultVals
End Function
I can see option 3 is probably the most self-contained, option 1 probably the least. Option 3 is likely the most memory-taxing and also requires the result to be split fairly messily.
Personally I choose option 2 as a middle ground, as I think as long as you are aware of the risks of byRef as you are typing the routine, once that's finished you can essentially forget about it as the variables won't be visible anywhere else in your code - unlike in option 1.
But have I missed something? And is any of these approaches standard practice that I should probably follow?