|Figure 1: The VBA Project Explorer|
showing folders for Class Objects, Modules and
Class Objects contain code relating to elements in a form or report. We covered these in some detail in the Learning Access VBA series of posts. As you may remember, code from class modules is generally triggered when a form or report event is triggered (for example, the OnCurrent Event is triggered when the user moves into a record displayed on a form).
With the partitioning of class objects, modules and class modules, VBA Projects have the potential to become very large and complicated. On the one hand these different project 'zones' need to be self contained so something happening in one class module does not interfere with something happening in another elsewhere; yet on the other, they also need to exchange information and communicate. This is where the concept of Scope comes in.
The concept of scope relates to the way in which different zones of a VBA Project partition the processing of data that occurs within and between each of those sections. We are going to illustrate how this works in relation to variables and sub procedure/function calls. Lets start with how variables behave within a form's object class.
|Figure 2: A basic Class Object to illustrate Scope .|
Variables and Scope
The screenshot in figure 2 shows a class object containing two sub procedures, Form_Load() and mySub(). A total of three variables are declared within the class object, two of which, - varB and varC -are contained within sub procedures. VarA on the other hand is declared above both sub procedures in what is known as the General Declarations section. The difference in positioning has a direct effect on the scope of each variable. Let's examine this in more detail.
VarB is declared within the form's Form_Load() sub. This means the scope of varB is local to this sub, and can only be accessed by code within it. As such, we can can only read and write to this variable from within the same sub procedure in which it is declared. So, for example, if we assign a value to varB within the Form_Load() sub, we will not be able to read that value from code executed within mySub and vice versa. This is what is meant by a local variable.
VarA on the other hand is written within the General Declarations section outside of any sub procedure. The scope of any variable declared here is class object wide. That is, it can be accessed from anywhere within it's own class object. As such, we can assigned a value to varA in the Form_Load() sub, and then read that same value externally from mySub. What we can't do, however, is access the variable from outside of this particular class object. To do this we need to declare a Public Variable from a Module.
The scope of a public variable declared in a module is project wide - that is to say, it can be accessed from any class object, module or class module in the project. Public variables are declared using the Public Statement (as opposed to the usual Dim Statement) in the module's General Declarations section (see Figure 3 below for an example).
|Figure 3: The shows the Public Variable, varX, in the General Declarations section of Module1.|
Scope and Persistence
Before we move on to look at sub procedure and function calls, it is important to say something about the nature of scope and persistence. In the context of scope, persistence is how long a value assigned to a variable lasts or persists. How long, that is, before the variable value is lost and forgotten. So, for example, if we assigned a value to a local variable declared within a sub procedure using the Dim Statement, that value will persist only as long as the sub procedure is running(1). Once the sub has finished the value assigned to the variable no longer persists. Likewise if a variable is declared within the general declarations section of a form class object, any value assigned to the variable will only persist whilst that form is still open. Once closed the value is lost. Of course it is public variables which have the greatest persistence. Any value assigned to one of these will last until the database application is closed.
(1) There is an exception to this rule. We can declare the variable using the Static Statement instead of Dim. Doing so enables the value to persist, but only within the sub where it has been declared. The next time that particular sub executes, the previous variable value is remembered and can be read by code (providing that code is still within the same sub).
Dim varThis As Integer
varThis = 10
Private Sub thatSub(argReceived As Integer)
MsgBox ("The argument received is: " & argReceived)
|Figure 4: The message displayed from the|
MsgBox method in thatSub.
In this post we have seen how the VBA project is partition into various zones, and how those zones are largely self contained in terms of data processing. This partitioning is maintained via a set of rules collectively known as scope, the advantage of which is the management of code within the project. Since there is a legitimate requirement for these zones to exchange information, the working of scope can be bypassed in a managed manner through the passing of parameters and receipt of arguments.