In VBA, the three scopes available for variables are public, module and procedure – usually referred to as Global, Module-level and Local. Global variables are recognised by every module in the active workbook. Module-level variables are available to all of the procedures in that module, but are not available to procedures in other modules. A Local variable is recognised only within the procedure in which it is declared
The Scope Chain
The scope chain is a list of objects that define the variables that are in scope. When the interpreter starts to resolve a variable, it looks at the first object in the chain. It it doesn’t find it, it looks at the next object in the chain. If that doesn’t have it, the search moves on to the next object, as so on until it arrives at the Global object where, if it fails to find the variable, it throws a ReferenceError.
Each function has its own object. So, a function defined on the global object has two objects in its scope chain – itself and the global object. A function defined within another function has three or more objects in its scope chain – itself, the objects of its outer function(s) and the global object.
The following code illustrates the scope chain:
A consequence of the scope chain is that, while inner functions have access to variables of their outer functions, the reverse is not true. To prove this, change the line:
document.getElementById("p2").innerHTML = a+"-"+b;
document.getElementById("p2").innerHTML = a+"-"+b+"-"+c;
and you’ll see things don’t work properly. If you look at the console output in the dev tool you’ll see an ‘is not defined’ error.
Thinking about scope in this way – ie. it being a series of linked objects that contain variables – helps us to understand another curious feature of the language: Hoisting.
Consider the below code:
If you run the above you’ll get the results:
a = undefined a = Hello World!
The above code results in a blank page. If you check the Console in the dev tool (F12 in IE, Ctrl+Shift+I in Chrome) you’ll see a ReferenceError. It’s also worth remembering that the rules governing variable hoisting operate in the same way for functions:
Here the call to myFunc still works as expected even though it’s not defined (declared) until after the call.
While Hoisting is a feature of the language its use is not considered good practice and you should maintain the habit of declaring your variables before they’re referred to by your code.