When you are creating your VB application you will find that you will need to store certain values. For example, after showing an options dialog, you will need to save the information selected to some variables so you can acess the data after the dialog box has been removed from the memory. You can use variables to store this information. They are called variables because they store variable information (information that changes)

In order to make you program easy to understand, and therefore easier to de-bug, it is a good idea to declare all your variables. Although VB does not force you it is a good habit to get into. Firstly it will save memory, by explicitly saying how big the variable will be, and also, if you ever use other languages like C++ you are not given the option of not declaring your variables. To declare a variable you use the following syntax: 

Scope  VariableName As DataType

Scope represents the range of the variable. VariableName is a string representing the name of the variable. DataType represents what sort of data is stored in the variable. If DataType is not specified, then it is set to Variant. For example,

Public NumberOfEmployees As Integer

if declared in the General Declarations section of a form, NumberOfEmployees can be  accessed and changed in all procedures in that form. NumberOfEmployees can only store an Integer.

To set the value of a variable you use the following syntax: 

VariableName = Value

Where VariableName is the name of the Variable, and Value is the value to be stored. An error will occur if Value is not the correct datatype for that variable. 

' General Declarations Section
Dim NumberofEmployees As Integer
' Form Load Procedure
Sub Form1_Load()
    ' Set the variable value
    NumberofEmployees = 150
End Sub

This sets the value of NumberofEmployees to 150 when Form1 Loads

To get the value contained in a variable, you simply put the variablename in place of where you would otherwise type the value:

' General Declarations Section
Dim NumberofEmployees As Integer
' Form Load Procedure
Sub Form1_Load()
    ' Set the variable value
    NumberofEmployees = 150
End Sub
' Command Button1 Procedure
Sub Command1_Click()
    Msgbox "The number of employees is: " & NumberofEmployees
End Sub

The previous code displays a message 'The Number of employees is 150' when Command1 is clicked.

You will find that quite often you need to refer to the same object a number of times. However, if you are refererring to that object using a property that will change, such as frmMain.ActiveForm, once the active form changes, you cannot refer to the object any more. 

In order to be able to do this, you can assign a variable to it. You do this in the same way as any other variable, except that you need to use the Set statment before the assignment:

Set ObjectName = Object

You also need to declare the variable as an object:

Dim ObjectName As Object

On occasions, you will know that the object that the variable will point to will always be a form, or a text box etc. If this is the case, you can declare the object as a text box. Visual Basic will create an error when you try to assign a different object to it. To access the objects properties, you simply use the variable name in place of the object:

Set objForm As Form1
' Sets Form1's Caption
objForm.Caption = "hello"

The following code assigns objForm to the ActiveForm in the MDI window (called MDIMain). You will notice that even if the ActiveForm property changes, the variable will still point to the same object:

Dim objForm As Form
' Assign Form
Set objForm = MDIMain.ActiveForm
' Set the caption
objForm.Caption = "Welcome"
' Activate another form
Form1.SetFocus
' Change the old active forms back colour
objForm.BackColor = vbRed
' Activate the old form
objForm.SetFocus

Once you have finished using an object in your code, you should remove the reference to the object. You can do this using the Nothing keyword. The following code sets objForm to refer to Nothing.

Set objForm = Nothing

If you ever try to access a variable that is an object when no object is assigned to it, you will get a run time error: 

Err 91
Object variable or With block variable not set

You must always assign an object to the variable before you can use it.

In Visual Basic, you can declare you own types or classes in a module or form. This will then behave as any other object in Visual Basic, except it only has properties. For example, the Screen object in Visual Basic exposes a number of properties, including FontCount and ActiveControl. These can be accessed by entering Screen.FontCount. You can create a custom version of this, that will allow you to define various elements that can store values. For example: 

Type EmployeeRecord    ' Create user-defined type.
    ID As Integer    ' Define elements of data type.
    Name As String * 20 ' Fill with 20 spaces
    Address As String * 30 ' Fill with 30 spaces
    Phone As Long
    HireDate As Date
End Type

This user-defined type has 5 properties. At the moment you cannot access them, as Visual Basic requires that you declare another variable that is referenced to this user-defined type:

Dim MyRecord As EmployeeRecord

Note that if you want to declare a Type in a form, it must be declared as private. So, the following code fills a few values into this user-defined type:

Private Type EmployeeRecord    ' Create user-defined type.
    ID As Integer    ' Define elements of data type.
    Name As String * 20 ' Fill with 20 spaces
    Address As String * 30 ' Fill with 30 spaces
    Phone As Long
    HireDate As Date
Private End Type

' Reference variable to user-defined type
Dim MyRecord As EmployeeRecord    ' Declare variable.

' Comment1_Click event.
Sub Command1_Click()
    ' Assignment to EmployeeRecord variable must occur in a procedure.
    
    MyRecord.ID = 12003    ' Assign a value to an element.
    MyRecord.Phone = 1813670690
End Sub 

When getting the value of a variable from a procedure or function parameter you have two ways to request it. Either you can request for it to be passed ByRef (default), or ByVal. 

Passing ByVal
Private Sub TestSub(ByVal strPath As String)

Passing ByRef
Private Sub TestSub(ByRef strPath As String) ' or just
Private Sub TestSub(strPath As String)

When you pass ByVal, Visual Basic passes a copy of the variable to the procedure. This way the procedure gets the value, but any changes it makes will not affect the original variable. 

When you pass ByRef, Visual Basic passes a pointer to the procedure. This is a reference so that the procedure knows where to find the variable in the memory. Any changes the procedure makes to this variable will effect the original one, as they are the same thing, however the variable does not need to be declared as public if you were wanting the procedure to access the variabl any other way. The following example shows the differences:

Sub Form_Load()
    Dim strTest As String
    '// fill the variable
    strTest = "Hello from Form_Load"
    '// call the procedure
    Call TestSub(strTest)
    '// display a message box containing the value of strTest
    Msgbox strTest
End Sub

'// TestSub procedure when passing ByVal
Sub TestSub(ByVal strString As String)
    strString = "Hello from TestSub"
    '// when control returns to Form_Load, no changes will have
    '// been made to strTest
End Sub

'// TestSub procedure when passing ByRef
Sub TestSub(ByRef strString As String)
    strString = "Hello from TestSub"
    '// when control returns to Form_Load, the value of
    '// strTest will have changed to Hello from TestSub
End Sub 

Note that when you are passing a variable ByRef, it must be declared as a specific datatype (ie string). Otherwise, VB cannot pass a pointer to it. If you do not do this, you will get a compile error:

ByRef Argument Type Mismatch.

This does not occur when passing ByVal. For example, the code below will produce a compile error when you press Command1:

Private Function TestFunction(ByRef sString As String)
    sString = sString & vbCrLf
End Function

Private Sub Command1_Click()
    Dim sTestString
    TestFunction sTestString
End Sub

while, the code below would not, as you have explicitly declared sTestString As String.

Private Function TestFunction(ByRef sString As String)
    sString = sString & vbCrLf
End Function

Private Sub Command2_Click()
    Dim sTestString As String
    TestFunction sTestString
End Sub
