Passing variable between Subs ?

xanadude

Newbie - but learning fas
Local time
Today, 21:01
Joined
Feb 2, 2011
Messages
65
Hi All Again

I was wondering how do you use a variable (Counter for instance) between different subs

What I have is a Private Sub MySub() that Calls a Public Sub MyOtherSub()

I have set the counter in MySub at the start to be 0

Do Some of my stuff then calls the Public Sub to do something else with If /Else If in. Depending what is done in the Called Sub the "Counter" will be changed from 0 to 1 or left at 0.
Then goes back to MySub to finish up.

The thing I cant seem to get my head around is why the Counter even when changed in MyOtherSub() is not changed in MySub().....

I have not got to learning modules and such yet
Sorry if this sound confusing.

Thanks
 
If you merely pass between the Functions local variables, that would be one way to accomplish what you speak of.

You can not do such with Subroutines as Subroutines may not return anything, only receive. That is the one difference between Functions and Subroutines.

If you were to develop in a Class, then you could create variables / attributes defined at the Class level. Those will be available to all Functions / Subroutines within the class.

You may define Public attributes to your class, which you may access those via ClassObjectName.AttributeName syntax. These have no business logic of their own... merely a named variable exposed as something touchable by external things to the class.

Also, with Classes you have the ability to use the Property type which are paired Getter / Letter functions which can perform VBA business logic surrounding updating the variable the Class is maintaining.
 
several ways


mysub calls anothersub

1. declare counter as a public variable in a module, and then either sub can update it.

Note that using public variables is best avoided if possible, though - so the following ideas are better. Tracking the use of many public variables can become difficult - it is better to redcue the scope of variables wherever possible. Generally it's a matter of taste and programming style, I think, as to which of the following ideas is best.


2. pass the counter into anothersub, and let anothersub adjust it,

Code:
sub mysub
dim counter as long
call anothersub(counter)
msgbox("counter is: " & counter)
end sub
 
sub anothersub(c as long)
some code to set c as appropriate
exit sub

note that the argument c can be declared byref or byval (default is byref). if byref then the REAL variable (ie counter) IS updated. If byval then anothersub makes a temporary copy, and the REAL variable is NOT changed.

Personally, I dislike having variables byref by default, as it is easy to change them without meaning to. I prefer byval as a default. However, if you are aware that byref is a default, things should be OK. Note that some variables types are always passed byref, even if you ask for them to be passed byval!

3. return the result as a function value, useful if the result can be a number other than 0 or 1

Code:
sub mysub
dim counter as long
counter = counter + anotherfunc
msgbox("counter is: " & counter)
end sub
 
 
function sub anotherfunc() as long
some code to set result of anotherfunc as appropriate
exit function

4. return the result of the function as a boolean


Code:
sub mysub
dim counter as long
if anotherfunc then counter = counter + 1
msgbox("counter is: " & counter)
end sub
 
 
 
function sub anotherfunc() as boolean
some code to set result of anotherfunc as appropriate
exit function
 
Last edited:
Thanks for this - WOW there are just so many ways to do these things.
Doing it the long way round for now but getting a great insight into the options there are out there

Thank you very much
 
I concur with Dave. Public variables are a last resort as they usually have excessive scope.

If the variables are declared in the declarations section of the module they have scope across all subs and functions within the module. However I prefer to pass them via arguments.
 
You can not do such with Subroutines as Subroutines may not return anything, only receive. That is the one difference between Functions and Subroutines.

Not really. ByRef arguments can pass values back from a Sub.

If you were to develop in a Class, then you could create variables / attributes defined at the Class level. Those will be available to all Functions / Subroutines within the class.

Not just for custom classes. This is also the case in the predefined Access object classes (Forms and Reports).
 
Personally, I dislike having variables byref by default, as it is easy to change them without meaning to. I prefer byval as a default. However, if you are aware that byref is a default, things should be OK. Note that some variables types are always passed byref, even if you ask for them to be passed byval!

Indeed. Best practice is to always declare ByVal or ByRef and of course be aware of which arguments will be ByRef regardless of your declaration.

Also, familiarise yourself with the effect of placing parentheses around parameters of a Sub. This can make a ByRef argument into a ByVal regardless of the declaration.

Another important difference is what happens when you Call a Sub instead of just using its name. Read my post in this thread and follow the link too.
 
Last edited:

Users who are viewing this thread

Back
Top Bottom