vba - Optimal way of altering multiple values with a function -
functions in vba @ least can ever return 1 thing. thing contain multiple values, it's still 1 package.
i create sub/function has effect on values of more 1 variable. far know, these 3 ways of doing that:
1. declare variables outside caller sub
private val1 long, val2 long sub caller() val1 = 1 val2 = 2 valuechanger debug.print val1 + val2 'prints 5 end sub sub valuechanger() 'no need pass values, pass both byval val1 = val1 + 1 val2 = val2 + 1 end sub
2. pass byref
sub caller() dim val1 long, val2 long val1 = 1 val2 = 2 valuechanger val1, val2 debug.print val1 + val2 'prints 5 end sub sub valuechanger(byref value1 long, byref value2 long) value1 = value1 + 1 value2 = value2 + 1 end sub
3. return both in single "packet"
sub caller() dim val1 long, val2 long, results() long val1 = 1 val2 = 2 results = valuechanger(val1, val2) debug.print results(1) + results(2) 'prints 5 end sub function valuechanger(byval value1 long, byval value2 long) long() 'return array, equally return collection or string dim resultvals(1 2) long resultvals(1) = value1 + 1 resultvals(2) = value2 + 1 valuechanger = resultvals end function
i can see option 3 self-contained, option 1 least. option 3 memory-taxing , requires result split messily.
personally choose option 2 middle ground, think long aware of risks of byref
as typing routine, once that's finished can forget variables won't visible anywhere else in code - unlike in option 1.
but have missed something? , of these approaches standard practice should follow?
your third method conceptually simplest, , possibly easier debug (and less need debugging in first place). can simplify mechanics:
1) use variant
pass arrays , functions
2) use array()
package information return
3) write sub sort of inverse array()
, 1 can unpack array list of provided variables (which implicitly uses vba's default byref
semantics:
sub unpack(a variant, paramarray vars() variant) 'a 0-based array of same length vars 'the elements of assigned variables in vars dim long = 0 ubound(vars) vars(i) = a(i) next end sub
then valuechanger()
be:
function valuechanger(byval value1 long, byval value2 long) variant valuechanger = array(value1 + 1, value2 + 1) end function
used like:
sub caller() dim val1 long, val2 long, results variant val1 = 1 val2 = 2 results = valuechanger(val1, val2) unpack results, val1, val2 debug.print val1 + val2 'prints 5 end sub
or just:
sub caller() dim val1 long, val2 long val1 = 1 val2 = 2 unpack valuechanger(val1, val2), val1, val2 debug.print val1 + val2 'prints 5 end sub
alternatively, can implement method 3 expanding mean "packet". typically makes sense return multiple values function when values in sense go together. suggests natural wrap values in type or class:
'at top of module: type pair val1 long val2 long end type
then:
function valuechanger(p pair) pair 'can't pass user-defined type byval dim q pair q.val1 = p.val1 + 1 q.val2 = p.val2 + 1 valuechanger = q end function
used like:
sub caller() dim p pair p.val1 = 1 p.val2 = 2 p = valuechanger(p) debug.print p.val1 + p.val2 'prints 5 end sub
Comments
Post a Comment