Basic VBA syntax
Storing data—variables, arrays, and constants
VBA operators
Conditional and loop statements
Writing and calling procedures
VBA, or Visual Basic for Applications, is the programming language built in to the programs in the Microsoft Office suite, including Outlook. To be able write and edit Outlook macros, you must have a decent understanding of the VBA language. Fortunately, it is a fairly easy language, having been designed from the very beginning to be accessible not just to computer geeks but also to us ordinary mortals.
This chapter provides an introduction to the VBA language, giving you an overview of the most essential language elements. It is by no means a complete treatment of VBA—that would require an entire book in itself! With the information provided in this chapter, you can start writing useful macros. As your needs and interest dictate, you can find more information on VBA in the online help, books, and other sources.
A VBA program, or macro, is made up of a series of VBA statements. Each statement is an instruction that tells Outlook to perform an action such as adding two numbers or opening an email message. Each statement is on its own line in the source code, although long lines can be split with a space followed by an underscore in order to make them easier to read in the editor. Thus, the following is treated as a single line of code:
ActiveWorkbook.CustomDocumentProperties.Add _ Name:="Part number", LinkToContent:=False, _ Type:=msoPropertyTypeNumber, Value:=566
Outlook is very literal when it comes to running VBA code. It can do only what you specify in the code—it has no way of knowing what you really meant. Even the slightest misspelling or punctuation error will cause problems, so you need to be careful. Fortunately, the case of words does not matter.
A comment is text in your macro code that is for information only—it has no effect on how the macro operates. Comments are useful—in fact they are recommended—for describing how your code operates. Then, when you or someone else needs to edit the code sometime down the road, its operation will be clear and not a matter of guesswork.
To create a comment, start a line with either an apostrophe or REM
. You can put a comment at the end of a line of code using the apostrophe but not REM
:
Rem This is a comment. ' This is another comment. Dim S As String ' This too is a comment. Dim S As String Rem But this is not permitted.
Many macros need some way to store data while they are running. This is temporary storage and lasts only while the macro is running—it is not permanent such as saving something to disk. VBA gives you a full range of options for storing data.
A variable is a place where you can store a single piece of information, such as a number of a segment of text. The name "variable" comes from the fact that the information can change while the macro is executing—it is not fixed. When you create a variable, you assign it a name, and then you use that name to refer to the variable in your source code. VBA variable names must follow these rules:
Do not use one of VBA's keywords.
The maximum length is 255 characters.
The first character must be a letter.
The name cannot contain a period, space, or any of these characters: ! @ # & % $.
The case of names is irrelevant, although the VBA Editor automatically adjusts case to be the same for all instances of a given variable name. For example, if the first time you use a variable you call it Count
, and the second time you type in COUNT
, the second entry will be changed to Count
by the editor.
You should use descriptive variable names—that is, names that describe the data the variable holds. For instance, a variable that holds an interest rate might be called IntRate
or InterestRate
. You could call it MickeyMouse
or Q99
and VBA would not care, but descriptive names make your code a lot easier to read and debug.
It is common practice, although not required, to use a combination of upper- and lowercase letters for variable names as shown in these examples:
TotalOfIncome
AverageSize
RecipientEmailAddress
All variables should be declared before being used for the first time. This tells VBA about the variable, specifically its name and the kind of data it will hold. A variable declaration takes this form:
Dim varname As type
varname
is the name of the variable, and type
is the name of the variable's data type (as explained in the following sections). You can place multiple declarations on the same line:
Dim varname1 As type1, varname2 As type2, varname3 As type3
I say that variables should be declared, not that they must be declared. VBA gives you the option of not requiring variable declaration—you simply use new variable names as needed in your code. This may sound like a good idea, but in fact it is not. When variable declaration is required, misspelling a variable name results in an error message when you run the program, because the (misspelled) variable has not been declared, and the misspelling can be easily corrected. If variable declaration is not required, misspellings go undetected and can cause lots of problems. To make sure variable declaration is required, select Tools, Options in the VBA Editor and select the Require Variable Declaration option on the Editor tab. You can obtain the same effect by placing the Option Explicit
statement at the start of every VBA module.
Numeric variables hold number data. VBA has six different numeric variable types that differ in whether they hold integer data (numbers without a decimal part such as 2, −145, and 32,190) or floating-point data (numbers with a decimal part such as −1.143, 0.0045, and 123,900.5). These six numeric variable types are summarized in Table 23.1.
Table 23.1. VBA's Numeric Data Types
Type | Range | Precision | Size | |
---|---|---|---|---|
Byte | Integer | 0 to 255 | N/A | 1 byte |
Integer | Integer | −32,768 to 32,767 | N/A | 2 bytes |
Long | Integer | −2,147,483,648 to 2,147,483,647 | N/A | 4 bytes |
Single | Floating point | −3.4 × 1038 to 3.4 × 1038[a] | 6 digits | 4 bytes |
Double | Floating point | −1.79 × 10308 to 1.79 × 10308[a] | 14 digits | 8 bytes |
Currency | Floating point | −9.22 × 1011 to 9.22 × 1011[a] | 4 digits | 8 bytes |
[a] Approximate values |
Why have three integer types and three floating-point types? You can see that the types differ in terms of the range of values they can hold and, for the floating-point types, their precision or accuracy. They also differ in the amount of memory they consume. It's also true that certain operations, such as division, are faster with the integer types. To be honest, these memory and speed differences are rarely relevant with today's fast, memory-laden computers. Choose a numeric data type based on the range of values the variable will hold. When in doubt, it is always advisable to err on the side of caution, using a type Long
rather than a type Integer
, for example. If you try to store an out-of-range value in a variable, VBA generates an Overflow
error.
Strings, which is just programmer-talk for text data, represent the second main class of data that VBA programs work with. VBA provides two types of string variables. A variable-length string can hold any amount of text up to about 2 billion characters. A variable-length string expands and contracts automatically to fit the data you put in it, so you do not need to specify the size when declaring it:
Dim City As String
A fixed-length string, on the other hand, has a fixed size you specify when the variable is declared. This can range from 1 to as many as approximately 64,000 characters. The declaration syntax is as follows:
Dim FirstName As String * 15 Dim LastName As String * 15
If you assign text that is too long to a fixed-length string variable, the extra part of the text is cut off and lost.
VBA can figure out that you mean to use s
as a number even though it was declared as a string, so the division is performed properly with the result that i
is equal to 8.
As its name implies, a constant is program data whose value does not change. VBA has two types of constants, literal and symbolic. A literal constant is a number or string typed directly into your code. String literals are typed in double quotation marks. Numeric literal constants are typed without special formatting. In this code, "Jackson"
and 0.75
are literal constants:
Dim Ratio As Single Dim Name As String Max = 0.75 Name = "Jackson"
A symbolic constant has a name. To create a symbolic constant, use the Const
keyword:
Const CONSTNAME As Type = value
The rules for constant names are the same as for variables. I like to use all uppercase names with underscore separators for constants, which makes them easily distinguishable from variables in the code (which are commonly written with a combination of upper- and lowercase). Thus, PRIME_RATE
is easily identified as a constant, and PrimeRate
is clearly a variable. The As
type part of the declaration is optional and is required only if you want the constant to be stored as a specific data type. value
is the constant value.
Here are two examples:
Const PRIME_RATE As Double = 0.042 Const FILE_SAVE_PATH = "c:my documentsdatabases"
A big advantage of using symbolic constants is that you can change the value of a constant throughout the program simply by editing its declaration statement. Another advantage is that the constant's name can help in making the program easier to read.
Boolean variables can hold only the two values True
and False
. They are widely used in all areas of programming because you'll find that you often need to store values that are true/false, yes/no, or on/off. You assign values to Boolean variables using the VBA keywords True
and False
. Here's an example:
Dim TaskDueToday As Boolean TaskDueToday = True
Behind the scenes, VBA represents True
and False
by the values −1
and 0
, respectively. When treated as a Boolean, any numeric expression will evaluate as True
if its value is non-zero.
In VBA, the term "date"
refers to the time of day as well as the calendar date. Dates are stored internally as floating-point numbers in which the part to the left of the decimal point represents the number of days since December 30, 1899, with negative numbers representing prior dates. The part to the right of the decimal point represents the time as a fraction of a day, so that .25
is 6 A.M., .5
is noon, and so on.
The Date
data type is designed to hold date values. When you display a date value, the display format is determined by the system's short date format setting, and times are displayed as either 12- or 24-hour times, again in accordance with the system settings.
You write literal date values in just about any recognizable format, enclosed in #
signs. Here are some examples:
Dim d1 as Date, d2 As Date, d3 As Date d1 = #January 31, 2005# d2 = #31 Jan 05# d3 = #1/31/2005#
The VBA Editor will automatically convert date literals to a standard format. VBA has a wide range of tools for working with dates and times. They are beyond the scope of this chapter, but you can find detailed information on the VBA online documentation.
The Variant
data type is VBA's default variable type, and also its most flexible. Default means that if you declare a variable without specifying a type, it is created as a Variant
. These declarations create two type Variant
variables:
Dim x Dim y As Variant
This data type's flexibility comes from its ability to hold almost any type of data (with the single exception of fixed-length strings). Thus, a type Variant
can hold numbers, text, object references, user-defined types, and arrays. One common use for this data type is when data needs to be treated either as text or as a number depending on circumstances. Another use is as an argument to procedures that can take different kinds of data. You should not, however, simply use type Variant
as a convenience to avoid the necessity of thinking about what data type should be used for specific variables. The Variant
data type requires more memory to store, and more processor time to manipulate, than other data types.
Another type of variable holds a reference to an object. Objects, which represent the various parts of the Outlook program (among other things), are a central part of VBA programming. You learn more about object variables when you look at Outlook's Object Model in Chapter 24.
An array is a group of two or more variables that have the same name and are distinguished by a numeric index. VBA offers two types of arrays: static and dynamic.
A static array is created with a specified number of elements and this number does not change while the program is executing. To declare a static array, use the following syntax:
Dim ArrayName(n) As type
ArrayName
is the name of the array, which follows the same naming rule as regular VBA variables. n
is the number of elements in the array, and type
can be any of VBA's data types. Here's an example:
Dim NewArray(100) As Long
This statement creates an array of type Long
variables. VBA starts array indexes at 0; this array actually contains 101 elements, at indexes 0 through 100. You access an array's elements using any expression to specify the index. For example:
NewArray(1) = 25 x = 15 NewArray(x) = 99 ' Same as NewArray(15) NewArray(MyArray(1)) = 5 ' Same as NewArray(25)
You can also create arrays where the index does not start at 0 by using the To
keyword, which lets you specify any starting index you like. The format is as follows:
Dim NewArray(start
Tostop
)
start
and stop
are the starting and ending indexes for the array. Here's an example:
Dim Months(1 To 12)
The arrays you have seen so far have a single index—they are one-dimensional. VBA also supports multidimensional arrays that have two or more indexes by including the information about the additional indexes in the Dim
statement. Here's an example that creates a two-dimensional array:
Dim ChessBoard(1 To 8, 1 To 8) As Integer
A dynamic array does not have a fixed size—it can be enlarged or shrunk while the program is running. The syntax for declaring a dynamic array is the same as for static arrays except that no indexes are specified—the parentheses are left blank:
Dim MyDynamicArray() As type
Before you can use the array, you must set its size using the ReDim
statement:
ReDim MyDynamicArray(indexes
)
The indexes
argument specifies both the number of dimensions and the number of elements, using the same syntax as you learned about earlier for declaring static arrays. Here are some examples of declaring and sizing dynamic arrays:
Dim DynamicArray1() Dim DynamicArray2() Dim DynamicArray3() ' 1 dimension, 21 elements 0-20. Redim DynamicArray1(20) ' 1 dimension, 26 elements 5-30. Redim DynamicArray2(5 to 20) ' 2 dimensions, 40 total elements. ReDim DynamicArray3(1 To 4, 1 to 10)
You can change the array size while the program is running as many times as needed using this syntax:
ReDim [Preserve]arrayname
(indexes
)
indexes
specifies the new array size, as shown here. Use the optional Preserve
keyword if you want the existing data in the array to be kept. If you omit Preserve
, the array will be reinitialized and existing data lost when you execute ReDim
. There are some limitations on the use of Preserve
:
When you make an array smaller, the data in the part of the array that is "trimmed off" will be lost.
You cannot change the number of dimensions of the array.
For multidimensional arrays, you can change only the upper bound of the last dimension.
A user-defined type, or UDT, can be used to define your own data structures. A UDT contains two or more elements and is designed to meet specific data storage needs of your macro. To define a UDT, use the Type ... End Type
statement:
Type UDTName Element1 As type Element2 As type .... Elementn As type End Type
Each element can be any of VBA's data types: Byte, Boolean, Integer, Long, Currency, Single, Double, Date
, variable-length or fixed-length String, Object, Variant
, another UDT, or an object type. Each element can be a single variable or an array. The rules for naming the UDT itself and it elements are the same as the rules for naming VBA variables as described earlier in this chapter.
Once you have defined a UDT, you declare it using the Dim
statement. A UDT must be declared in a module but not within any procedure. Here's a UDT definition:
Type Person FirstName As String LastName As String EmailAddress As String End Type
Then declare in a variable of this type:
Dim MyBestFriend As Person
Finally, access the elements of the UDT using the VariableName.ElementName
syntax:
MyBestFriend.FirstName = "Alice" MyBestFriend.LastName = "Wilson" MyBestFriend.EmailAddress = "[email protected]"
You can create arrays of UDTs as well:
Dim AllMyFriends(100) As Person
An enumeration is a user-defined data type that consists of a defined set of symbolic constants. You use the Enum
keyword to create an enumeration as shown in this example:
Enum Flavors Vanilla
Chocolate Strawberry Banana End Enum
This creates an enumeration called Flavors
with the constants Vanilla
equal to 0, Chocolate
equal to 1, and so on. If you do not want the enumeration values assigned sequentially starting at 0, you can specify the values:
Enum Flavors Vanilla = 2 Chocolate = 3 Strawberry = 5 Banana = 10 End Enum
Enumerations can be defined only at the module level. Once an Enum
is defined, it becomes available as a data type you can use to declare variables:
Dim IceCreamCone As Flavors
A variable declared as an enumerated type can only take on the set of values defined in the enumeration. A real convenience is that VBA displays autolist members for enumerated types, permitting you to select from a list of the enumeration's constants.
Operators are symbols that instruct VBA to manipulate data in some manner, for example multiplying two numbers. The operators available in VBA fall into several categories.
The assignment operator (=) tells VBA to assign a value to a variable. Specifically, the value of the expression on the right side of the operator is assigned to the variable on the left side of the operator. For example, the statement
x = 15
assigns the value 15 to x
.
The mathematical operators perform the common operations such as addition and division. There are the four common arithmetic operations as follows:
+ Addition - Subtraction * Multiplication / Division
There are three others that are perhaps less common:
:
Integer division without rounding. For example, 15 4
evaluates to 3.
^:
Exponentiation (to the power of). For example, 2 ^ 4
evaluates to 16.
mod:
Modulus (remainder after division). For example, 33 mod 6
evaluates to 3.
For both division operators, a Divide by Zero
error occurs if the divisor is 0.
There is one string operation called concatenation, which simply joins two strings together. The operator for this is &
. For example, after this code:
Dessert = "Chocolate" & "cake"
the variable Dessert
contains "Chocolate cake"
. There are lots of other things you can do with strings, but they involve functions rather than operators. You can find information on these functions in VBA's online documentation.
You use comparison operators to perform comparisons between two expressions. The result of a comparison is either True
or False
depending on whether or not the comparison was true. The most commonly used comparison operators, which are used primarily with numeric expressions, are
=
Is equal to?
>
Is greater than?
<
Is less than?
>=
Is greater than or equal to?
<=
Is less than or equal to?
<>
Is not equal to?
For example, the expression
a < b
asks the question "is a less than b?" and returns either True or False depending on the values of a
and b
.
You use logical operators to manipulate logical (True/False) expressions. Most of the logical operators combine two logical expressions into a single logical value. The logical operators are described in Table 23.2.
Table 23.2. The Logical Operators
Operator | Example | Evaluation |
---|---|---|
|
| True if both |
|
| True if |
|
| True if |
|
| True if |
|
| False only if |
|
| True if |
The logical operators are often used in conjunction with the comparison operators. For example, the following expression evaluates as True only if x
is equal to 5 and y
is not equal to 0:
(x = 5) And (y <> 0)
When an expression contains more than one operator, it may not always be clear how the expression evaluates. For example, look at this expression:
20 / 4 + 6
How should you read this?
If the addition is performed first, the expression evaluates to 2 (4 plus 6 is 10, 20 divided by 10 is 2)
If the division is performed first, the result is 11 (20 divided by 4 is 5, 5 plus 6 is 11).
Potentially ambiguous expressions such as this one are resolved by VBA's rules of operator precedence, which determine the order in which operations are performed. The precedence of VBA's operators is given in Table 23.3. Operators with lower precedence numbers are performed first.
Operators that have the same precedence level, such as multiplication and division, are executed in left-to-right order.
With this information on the precedence rules, you can see that the previous example will evaluate to 11 because the division will be performed before the addition.
You can use parentheses in an expression to modify the order of execution. Those parts of an expression enclosed in parentheses are always evaluated first regardless of operator precedence. Therefore,
20 / (4 + 6)
evaluates to 2 because the parentheses force the addition to be performed before the division. You can use as many parentheses in an expression as you like as long as they always come in pairs with each left parenthesis having a matching right parenthesis. Nested parentheses—when one set is inside another set—execute starting with the innermost set and proceed outward.
An important part of VBA programming is controlling which VBA statements execute and when. VBA has several tools for this purpose, the two most important being loop statements and conditional statements.
A loop statement is used to execute a block of VBA statements a certain number of times. There are three loop statements.
The For...Next
statement executes a block of statements a prespecified number of times. It is written like this:
Forindex
=start
Tostop
Stepstep
... statements ... Nextindex
index
is a numeric variable that serves as the loop counter.
start
and stop
are the starting and ending values of index.
step
is the amount that index
is incremented with each repetition of the loop. If you omit the step
value, the default increment of 1 is used.
When a For...Next
loop is encountered, here's what happens:
index
is set to the value of start
.
index
is compared to stop
.
If index
is less than or equal to stop
, the statements in the loop are executed. If not, the loop terminates.
index
is incremented by the value of step
(or by 1 if step
is not specified).
Return to step 2.
This For...Next
loop sets the values of the array to 0, 4, 8, ... 200:
Dim NewArray(50) As Integer Dim j As Integer For j = 0 To 50 NewArray(j) = j * 4 Next j
Code inside the loop should never change the value of the counter variable.
It is possible to use a For...Next
loop to count down by making step
negative. When you do this, start
must be greater than stop
, and the loop terminates when counter is less than stop
. In this example, the For...Next
loop fills the elements of the array with the values 100, 99, ... 0.
Dim NewArray(100) As Integer Dim j As Integer For j = 100 To 0 Step −1 NewArray(j) = 100 - j Next j
If you want to exit from a For...Next
loop early—that is, before the index variable reaches its final value—use the Exit For
statement.
VBA permits you to nest For...Next
loops within each other. Each inner loop must be totally within the outer loop.
You use the For Each...Next
loop to execute a group of statements once for each member of a collection. It is used to go through a collection and do something to or with each member. The syntax is
For Eachitem
incollection
... statements ... Nextitem
item
is the variable used to iterate through the collection and must be declared as a data type appropriate for the members of the collection. This is usually the same data type as the collection contains, although you can use type Object
or Variant
as well.
collection
is the name of the collection. The statements are executed once for each element in the collection.
Here's an example that sets the Color
property of all objects in the collection to Blue
:
Dim o As Object For Each o In SomeCollection o.Color = Blue Next o
You'll see plenty of examples of using For Each...Next
when you start looking at the Outlook Object Model.
The Do...Loop
statement executes a block of statements repeatedly as long as a specified logical condition is met. Depending on how the Do...Loop
statement is written and where the logical condition is placed, the statements may be executed no times, a single time, or multiple times.
This statement has several slightly different syntaxes. To execute statements repeatedly as long as a logical condition is True, use the While
keyword:
Do While condition
...
statements
...
Loop
You can also execute statements repeatedly as long as a condition is False by using the Until
keyword:
Do Until condition
...
statements
...
Loop
When program execution reaches the Do
statement, condition
is evaluated. If it is True (if using While
) or False (if using Until
), the statements are executed and then condition
is evaluated again. This continues until the value of condition
changes. Depending on the initial value of condition
, the statements in the loop may not be executed even once.
You can also write a Do...Loop
statement that tests condition
at the end of the loop. As before, you can use either While
or Until
:
Do ... statements ... Loop Whilecondition
Do ... statements ... Loop Untilcondition
When you use this syntax, the statements are executed once and then condition
is evaluated. By testing condition
at the end of the loop, you ensure that the statements in the loop will be executed at least once.
To exit a Do...Loop
early, use the Exit Do
statement.
VBA's conditional statements are used to execute or not execute a block of statements depending on a program condition. The statements are executed once or not at all. There are two conditional statements in VBA.
The If...Then...Else
statement executes a block of statements if a specified condition is True. Optionally, a second block of statements is executed if the condition is False. The syntax is
If condition
Then
block1
Else
block2 End If
condition
is a logical expression. If it is True, the statements in block1
are executed. If condition
is False, the statements in block2
are executed. The Else
keyword and the second block of statements are optional. If they are omitted, no statements are executed if condition
is False.
You can test multiple conditions in an If...Then...Else
statement by using the ElseIf
keyword. Here's how this is written:
Ifcondition1
Then block1 ElseIfcondition2
Then block2 ElseIfcondition3
Then block3 .... Else block4 End If
There's no limit to the number of ElseIf
s. The testing of the various conditions starts at the top and works downward. As soon as a True condition is found, the corresponding block of statements is executed and execution exits the If
statement. One block of statements at most will be executed regardless of how many of the conditions are True.
When you need to test multiple conditions, it is usually easier to use the Select Case
statement, covered next.
The Select Case
statement evaluates a single expression and compares the result with a series of templates. If it finds a match, the associated block of statements is executed. The syntax is
Select Caseexpression
Casetemplate-1
statements-1 Casetemplate-2
statements-2 .... Casetemplate-n
statements-n Case Else statements-else End Select
expression
is evaluated and the result is matched against the various templates, in order from top to bottom. When a match is found, the following block of statements is executed. If no match is found, the statements following the Case Else
are executed. The Case Else
keyword is optional. Even if more than one template matches, only a single block of statements will be executed—the block that follows the first matching template.
Each template in a Select Case
statement can contain one or more of the following elements:
Any expression. The test expression must match the template exactly.
Two expressions separated by the To
keyword. The test expression must fall within the range specified by the two expressions. For example, 0 To 50
.
The Is
keyword followed by a comparison operator and an expression. For example, Is > 10
.
You can use multiple elements in a template, separating them by commas. This example defines a template that would match if the test expression evaluated to 0, to any value between 5 and 10, or to any value greater than 25:
Case 0, 5 To 10, Is > 25
A procedure is a section of VBA code that is independent and has been assigned a name. In fact, every Outlook macro is a procedure, and it is the procedure names that you see listed in the Macros dialog box. However, whereas all macros are procedures, not all procedures are macros. This kind of procedure can be very useful in your VBA programming.
Say you have written a number of macros that manipulate and organize your email, tasks, and so on. Each macro, as part of its operation, needs to sort a list of items into alphabetical order. Rather than including the VBA code that performs the sort in each and every macro, you can place the code in a separate procedure and then call the procedure as needed from each macro.
VBA supports two kinds of procedures, Subs and Functions. They are identical except for the fact that a Function returns data to the calling program, whereas a Sub does not.
To define a Sub procedure, the basic syntax is
Subsubname
(argumentlist
) ... ' Code is placed here ... End Sub
The syntax to define a Function is similar:
Functionfunctionname
(argumentlist
) Astype
... ' Code is placed herefunctionname
= returnvalue End Function
For both types of procedures, the name must follow VBA variable naming rules and also must be unique within the module where the procedure is located. argumentlist
is an optional list of data passed to the procedure when it is called (as explained in the next section). For a function, the As type
clause specifies the data type of the function's return value, and the functionname = returnvalue
statement sets the value of that return value.
Many procedures have arguments that permit data to be passed to the procedure when it is called. The argument list can include as many arguments as are needed, and has the following syntax:
argname1
Astype, argname2
Astype
, .....
Here's an example of a function procedure that is passed three numbers and returns the largest one:
Function Largest(n1 as Double, n2 As Double, n3 As Double) _ As Double Dim temp as Double If n1 > n2 Then temp = n1 Else temp = n2 End If If n3 > temp Then Largest = n3 Else Largest = temp End If End Function
Each argument can be any of VBA's data types, including UDTs, arrays, or enumerations. To specify an array argument, use an empty set of parentheses:
Sub ProcessArray(array() As String) ... End Sub
Calling a procedure requires a different syntax for Sub and Function procedures. For Sub procedures you have two choices: You can use the Call
keyword, in which case the argument list must be in parentheses:
Call ProcedureName(ArgumentList)
Or, you can omit the Call
keyword and the parentheses as well:
ProcedureName ArgumentList
Because a function returns a value, it can be treated as an expression and used—that is, called—any place an expression could go. For example:
result = Largest(x, y, z)
You learned earlier in this chapter how to declare variables in your VBA programs. Most of the variables you use will in fact be declared within procedures. These are called local variables and they have some special characteristics that relate to scope.
Scope refers to the parts of a program where a variable is visible. You can use a variable only where it is in scope. In other parts of the program, it is out of scope and might as well not exist. In your VBA programs, you control a variable's scope by where the variable is declared:
A variable declared within a procedure is visible only within that procedure.
A variable declared at the module level—that is, outside any procedure—is visible in all procedures in that module.
This has implications for the programmer. You can use the same variable name in two or more procedures and they will be totally independent of each other. But what if you have a variable declared within a procedure and also use the same name for a variable declared at the module level? If a procedure contains a variable with the same name as a module-level variable, the local copy takes precedence. Otherwise, the module-level variable is visible within the procedure.
Now that you have learned something about how to write procedures, how do you actually go about it? The VBA Editor makes it easy:
In Outlook, press Alt+F11 to open the VBA Editor.
If necessary, double-click Module 1 in the Project Explorer to open that module for editing.
Select Procedure from the Insert menu to open the Add Procedure dialog box (see Figure 23.1).
In the Type section, select either Sub or Function depending on the type of procedure you want.
Type the procedure name in the Name box.
Click OK. The editor creates the shell of the Sub or Function procedure, ready for you to edit.
What is it that differentiates a macro procedure from a non-macro procedure? The main difference is whether you intend the user to execute the procedure directly from the Macros dialog box. In order to be considered a macro by Outlook and to be listed in the Macros dialog box, a procedure must meet two criteria:
It must not return a value—that is, it must be a Sub procedure and not a Function procedure.
It must not take any arguments.
Suppose, however, that you wrote a Sub procedure that takes no arguments, yet you do not want it listed in the Macros dialog box. You can "hide" it by using the Private
keyword:
Private MySub() ... End Sub
Now your other macro code will be able to call this Sub, but the user will not be able to execute it from the Macros dialog box.
Sometimes your macro will need to get some information from the user. Perhaps it needs to prompt for a name, or to get a Yes/No answer. VBA provides two tools for this purpose, MsgBox
and InputBox
.
The MsgBox
function displays a dialog box with a message and one or more buttons. The function's return value indicates which of the buttons the user clicked. You use this function as follows (I have omitted a couple of optional and rarely used arguments):
MsgBox(prompt, buttons, title)
prompt
is a string expression specifying the message to display in the dialog box.
buttons
is an optional argument specifying what buttons and/or icons to display in the dialog box and, when there is more than one button, which one is the default (the default is the one selected if the user presses Enter). If this argument is omitted, only an OK button is displayed. The possible settings for this argument are given in Table 23.4. To combine settings, use the Or operator.
title
is an optional argument that specifies the title displayed in the dialog box's title bar. If this argument is omitted, the application name is used as the title.
Table 23.4. Defined Constants for the MsgBox Function's buttons Argument
Constant | Value | Description |
---|---|---|
vbOKCancel | 1 | Display OK and Cancel buttons |
vbAbortRetryIgnore | 2 | Display Abort, Retry, and Ignore buttons |
vbYesNoCancel | 3 | Display Yes, No, and Cancel buttons |
vbYesNo | 4 | Display Yes and No buttons |
vbRetryCancel | 5 | Display Retry and Cancel buttons |
vbCritical | 16 | Display Critical Message icon |
vbQuestion | 32 | Display Warning Query icon |
vbExclamation | 48 | Display Warning Message icon |
vbInformation | 64 | Display Information Message icon |
vbDefaultButton2 | 256 | Second button is default |
vbDefaultButton3 | 512 | Third button is default |
As mentioned, the function's return value indicates which of the buttons the user selected. The possible return values are represented by the constants shown in Table 23.5.
Table 23.5. Defined Constants for the MsgBox Function's Return Value
Constant | Value | Button Selected |
---|---|---|
vbOK | 1 | OK |
vbCancel | 2 | Cancel |
vbAbort | 3 | Abort |
vbRetry | 4 | Retry |
vbIgnore | 5 | Ignore |
vbYes | 6 | Yes |
vbNo | 7 | No |
To use the MsgBox
function, call it with the appropriate arguments and then test the return value. Here's an example, with the displayed dialog box shown in Figure 23.2:
Dim retval As Integer retval = MsgBox("Delete file - are you sure?", vbYesNo, _ "Confirm delete") If retval = vbYes Then ' Code to delete file goes here. End If
You use the InputBox
function to return a string entered by the user. The syntax for this function is (I have omitted some optional and rarely used arguments):
InputBox(prompt, title, default
,)
prompt
is the text displayed as the prompt in the dialog box.
title
is an optional argument that specifies the title displayed in the dialog box's title bar. If this argument is omitted, the application name is used as the title.
default
is an optional string expression that specifies the default response if the user does not enter one. If this argument is omitted, the default response is an empty string.
This code uses the InputBox
function to get the user's country of residence, with "United States" being the default response. The displayed dialog box is shown in Figure 23.3.
Dim Country As String Country = InputBox("Your country of residence?", "Country", _ "United States")
This chapter has provided you with a quick introduction to programming macros with the VBA language. This information is sufficient to get you started writing your own macros (although you should read the next chapter before getting started). There's lots more to the VBA language, aspects that could not be covered here due to space limitations. You can further explore VBA on your own using the VBA Editor documentation, online resources, or books published on the subject.
18.224.67.84