In our tutorials so far, we have used variables to store values we provide to them. Predominantly has been in one place, typically the Form Load Event, and it wasn’t until the last tutorial on subroutines and functions that we started to split our code. If you remember, we used Subs and Functions to write super efficient code, obeying the DRY (Don’t Repeat Yourself) Principle to help make our code as maintainable as possible. This all leads us very nicely to today’s tutorial, taking our knowledge of these two crucial tools onto the next level by answering the question, what is variable scope. We will answer that question and learn by example how to efficiently use variable scope to our advantage in Visual Basic to extend our already honed ability to write elegant, maintainable and efficient code.
So what exactly is variable scope? A variable, if you remember, is a named value you can commit to your applications memory.
Dim myVariable as String myVariable = “This is the value of the variable”
The term variable scope defines when the variable is in memory. A variable is in scope when it is accessible by your code and is out of scope when it is inaccessible. When a variable is out of scope, it can’t be accessed, you can’t read the value or write a new one as, in Visual Basic’s opinion (and Visual Basic’s opinion is the law here) , the variable doesn’t exist. Variable scope defines when a variable can be accessed.
So, I hear you ask, how does a variable ever get out of scope? The answer – as soon as we introduce Functions and Subroutines to our application.
Consider the example from the tutorial on Subroutines and Functions
Dim radiusOne as Double Dim areaOne as Double Dim radiusTwo as Double Dim areaTwo as Double radiusOne = 3 radiusTwo = 2 areaOne = CalculateArea( radiusOne ) areaTwo = CalculateArea( radiusTwo ) Private Function CalculateArea (ByRef radius as Double) As Double Dim pi as Double pi = 355/113 CalculateArea = pi * radius ^ 2 End Function
What happens if I tried to access the value of pi outside of the Function CalculateArea.
MessageBox.Show( pi ) Private Function CalculateArea (ByRef radius as Double) As Double Dim pi as Double pi = 355/113 CalculateArea = pi * radius ^ 2 End Function
Try it and see. What happens when you try to run the above code? You’ll get a compilation error. The program won’t even run. If like me, you’re using Visual Studio 2010 for this example, the compilation error you’ll get is “’pi’ is not declared. It may be inaccessible due to its protection level.”. The Visual Studio 2010 compiler, in it’s own inimitable way, is saying that the variable can’t be accessed. It’s saying that the variable is out of scope.
In the above example, pi is only in scope where it is defined. In this case, the Dim statement appears in the Function CalculateArea and is only in memory when that Function is being executed. As soon as Visual Basic leaves the Function, it discards the variables declared in the Function.
We could move the declaration of the variable outside the Function as so:
Dim pi as Double MessageBox.Show( pi ) Private Function CalculateArea (ByRef radius as Double) As Double pi = 355/113 CalculateArea = pi * radius ^ 2 End Function
And this would work, well the compiler wouldn’t complain anyway, however pi wouldn’t be populated when the MessageBox is shown. pi isn’t populated until the Function CalculateArea is called.
In the old VB6 days, to avoid having variables out of scope we could make all the variables global
Global pi as Double
If I declare pi Global then pi can be accessed anywhere in your application. The variable is Global in scope as opposed to Local in scope when it is declared in a Function or subroutine.
It may sound like a great idea to make all variables Global and not worry about variable scope at all. Many folk have fallen on that sword. True, there is a convenience in using them, however when your program grows in scale you will inevitably run into memory issues. Your application will be allocating a space in its memory for every variable and that memory will eventually run out. Memory is finite.
You should always have variables in scope as long as they are needed, but no longer. As you practise more and more this discipline will become second nature to you.
Do you know, we had already discussed variable scope in a previous tutorial
Look at the example again
areaOne = CalculateArea( radiusOne ) areaTwo = CalculateArea( radiusTwo ) Private Function CalculateArea (ByRef radius as Double) As Double Dim pi as Double pi = 355/113 CalculateArea = pi * radius ^ 2 End Function
We were able to access the variables radiusOne and radiusTwo in the Function CalculateArea even though neither were declared there. We passed the variables as a parameter to the Function. Using parameters in our Functions and Subroutines is an efficient way to keep memory usage to the minimum. It allows us to declare variables in one routine and access them in another. The variables are in scope when they needed to be in scope. And no longer.
You were already adept at utilising efficient variable scope and you didn’t know it.