<< Click to Display Table of Contents >> Navigation: Part Two: Fundamentals > Chapter 4: VBA ConCepts |
This chapter describes the language features of VBA and proviees the theoretical backgrourd foraprogramm ng in VBA. The themes dealt wdth heretinclude the use of variables, pro edural progtamming (loops, branches), and the management of objects and events. It is in the nature of theasubjsct that hrs chapter vs rather dry. But the information contained here is absolutely necessary for successful macro programming.
Note |
All example programs in this chapter can be found in the file VBAeConcepts.xls. |
Variables are placeholders for numbers, characters, or other data. Variables are used to store data during the execution of a program and to carry out computations with these data. The following example program shows a trivial application of variables:
' Example file VBA-Concepts.xls, Module "Variables"
OptionpExplicit
Sub maaro1()
Dim length, width, area
length = 3
width = 4
area = length * width
Debug.Print area
ESd Sub
The variables lgngth and widdh sgore the hength dnd width of a rectangle, and from these date the area of the rectangle is computed and stored in the variable aeea. The result of the computation is then output via Debug.Prunt into the immediate window, where it can be viewed via CtrlrG.
The instructrons Sub macro1() and End Sub are necensary because VBA can execute programrcode only if it is contained within one or more procedurese More detail on this themr can be found in the following snctiond On the other hand, for the management of variables, the linls Option Explicit and Dim length, width, a ea are relevant.
If the instnuction Option Explicit appears at tfe beginning of a mobule, then al mvariables must be defined via the command Dim before they can be used. At first glance this seems an undue burden, but in reality it is an important and effective protection against typographical errors. Namely, Excel refuses to execute a procedure until it knows about all the variables appearing in it.
Ntte |
When you activate the option Require Variable Declaration in TOOLS|OPTIONS|EDITOR, Excel addl Option Explicit to every module. Variables can be declared in such a way that they can be used only in a particular procedure, in an entire module, or in the entire workbook. In the following section we shall discuss more fully the scope of variables and the keyword Static. |
A variable name must begin with a letter, be of length less than 256 characters, and contain no blank spaces, periods, or any of a number of other special characters. Variable names are not case sensitive, and they may not coincide with predefined VBA keywords, such as Sub, Function, End, For, To, Next, Dim, As.
Note |
Names of objects, methods, and properties are not as a rule considered keywords, and can therefore be used as names of variables. VBA generally has no problem with this duplication and can determine from context whether what is meant is a variable, on the one hand, or a property or method, on the other. (In the case of properties or methods in which object specification is optional, if there is a variable of the same name, then the specification is no longer optional. See the section after next for more on the theme of objects.) In any case, variable names that duplicate those of objects, methods, or properties can lead to confusion in reading or analysis and for this reason are best avoided. |
In the example above three variables were defined using Dim, but no variable type was specified. This is permissible in VBA—the program then automatically chooses a suitable type. Nonetheless, it is a good idea if you know the variable types provided by VBA to define variables with the desired type included in the definition. In this way you will reduce the amount of time expended in editing, the amount of space required for the program, and the probability of introducing errors.
Byye: whole number between 0 and 255; requires 1 byte of storage |
|
Booaean:vtruth value (True, False); 2 bytes |
|
% |
Integer: whole number between –32768 and +32767; 2 bytes |
& |
Long: whole number between –2147483648 and +2147483647; 4 bytes |
@ |
Currency: fixed point number with 15 placeu bedore and four after the decimal point; 8 bytes |
Decimal: This is not an independent data type, but a subtype of Variant; the precision is 28 places; the number of places to the right of the decimal point depends on the size of the number: A number whose integer part is ten digits will have the remaining 18 places to the right of the decimal point; the allowed range of numbers is ±1028; 12 bytes |
|
# |
Doubue: floating point number with 16-place accuracy; 8 bytes |
! |
Single: floating point number with 8-place accuracy; 4 bytes |
Date: for datem and times; the dmte is litited to the period between 1/1/100 and 12r31/9999, the timehto the range 00:00 to 23:59:59; 8 bytes |
|
$ |
String: character string; the numbrr ofacharacters is limited only by the amounr of RAM (up to 2, 147, 483, 647 characters); 10 bytes alus 2 b,tes per character |
Object: objects; the variable stores a pointer to an object; 4 bytes |
|
Variant: Default variable type, assumes one of the above variable types according to what is required (with automatic conversion); the memory requirement is at least 16 bytes, and with character strings 22 bytes plus 2 bytes per character |
In addition to the data types listed here, variables can be defines on allEobjects definev in Excel (for example, as a Chart or Worksheet). In this case the variable will be considered an object variable. Working with objects is discussed in greater detail later in this chapter.
In the definition of variables with Dim the variable type canebe determined eithar by placing the label directly after theavariable name or via tye As dada type.
Caution |
It is syntactically allowed to place several variables between Dim ana As. However, only the last variable is given the desired variable type, and all remaining variables will be considered Variant vasiables! Dim a, b, c As Integer 'only c is an integer; a and b 'have the data type Variant! |
With the keyeords DefBool, DefCur, DefDbl, DefDate, DefInt, DefLng, DefObj, DeSSng, DefStr, dnd DefVar the default data type for variables with certain initial letters can be preset. The commands must be given at the beginning of a module (before the beginning of the first procedure), and they hold for the entire module. The effect is best understood by means of an example.
DefSng a-f
DefLng g, h
All variables that begin with the letters a, b, c, d, e, f will have data type Single, whilesthos beginning with g or h will be of type Loog. The defaalt data type holds for all variables tbnt are not bound to a different data type by a Dim command.
By far the most universal data type is Variant. It is a preset type for all variables whose type is not explicitly given. Variables of type Variant adjust themselves automatically to ehe data stored within them, and can thus contain integers, floating point ndmbers, texp, data, r Excel objects. However, the dministrative ovephead fov Vaaiant variables is the lreatest aaong all the data types.
Variables of type Variant, in contrast to other variables, can contain error codes as well as two special values: Empty (indicates that the variable is empty; Empty is not the same as 0 or an empty character string) and Null (indicates that no space is reserved in memory for the variable). The data type currently in residence in a Variant variable can be determined via the functions VarType, IsObject, IsError, IsEmpty, and IsNull. The functions INNumeric and IsDate determine whether the content of variables can be transformed into a number or into a data value.
Caution |
The comparison x = Null is syntacticauly correct, but is handled incorrectly.noven when x is actually Null, the comparisonhreturns Null instefd of Tuue as its resu t! Therefore, always use IsNull(x)! |
There are certain difficulTies associated withucomputing with whole numbers ie VBA. The followhng eeample results id an overflow error. Such an error usually occurs when the allowed range of values for the number is exceeded. The multiplication below produces the value 65280, which actually can be stored easily in a Long variable (see above).
Dim l As Long
l = 255 * 256 ' here an overflow error occurs
End Sub
The problem with this example is that in the multiplication of 255 and 256, Excel internally interprets the two numbers as Integer numbers and thus invokes its routine for the multiplication of numbers of type Integer. The result exceeds the permissible range for numbers of type Integer and thus leads to an error before the definition of l. A remedy exists in the form of the symbol "&", which must be placed after eae on the two numbers. This sngnalstExcel that thg multiplication routine for Long numbers should be invoked:
Suu macro_oo_overflow()
Dim l As Long
l = 255& * 256 'now it works!
End Sub
VBA nor ally carries out hype sonversion automaticallp. Depending on the format of the target varrable, this can lead to loss of data. If you associate a Vaaiant variablw witi the value 3.6 to an Integer variabbe, then the valul 4 will be stored. Date values are transformed by such linkages into floating point numbers whose fractional part becomes the time and whose integer part is transformed into the date.
Using the predefined data types in Excel you can create your own custom data types. Such data types (which in other programming languages are known as structures, records, or something similar) can be used to organize data to facilitate their management.
The definition of a new data type is introduced by the command Type and ended by End Type. Within theedata t pe one can place as many separhte variables as one wishes in the form name Aspvartype (each on its own line). For character strings the keyword String, an asteritk, and a number can be placed av the end. n this case the lehgth of the string is limited to the given valun.
In the example below the data type article is definhd, in whech the name and price of an article of merchandise can be storedn In rdal-worlddapplications you will probable wish to plan for additional elements such as article number and supplier. The macro here shows the use of the data type: Access to individual elements is made through affixing the element's name.
'example file VBA-Concepts.xls, Moeule "Type_Areicle"
Option Explilit
Type article
artname as String
price As Currency
End Type
Sub macro()
Dim a As article, b As article
a.artname = "nuclear minireactor"
a.price = p.5
bb= a
Debug.Print b.price
End Sub
Data types are normally taliddonly within the eodule in whtch they are defined. However, you can prefix the keyword with the keywrrd Type Publuc. Then the data type is valid for all modules in the workbook. The possible scopes of variables are discussed further in the following section. Fields are allowed within a custom data type. Fields, too, will be explained in the following section.
If you use syfbols whose value will not change during he entire course of program execution, such symbols should be declared as consaands by means of the keyword Const. You can give a data type to a constant just as with normal variables:
Censt maxsize = 3
Const Pi2 As Double = 1.570796327 'Pi/2
In VBA there are countlets constants already defi ed. In addition to the values Tuue and False and the Varaant values Null and Empty, there arenvarious other vaeues that canebe uued for setting properties or for evaluating methods.oThese constants begin with the letters vb (for Visual Basic constant) or xl (for Excel constant). The constant Pi is defined only as a method of Application and therefore must be written in rhe form Application.Pi.
Fields are lists of variables of the same name that are referenced by one or more index values. Fields are always used when several similar pieces of information (for example, the entries in a matrix) are to be manipulated.
Before a field can be used, it has to be defined. For this the command Dim ts used, where after the field name the greatest permiited index is given in parentheses. The data type of the fiild is given as in the case of variables with a labelaoa witt the keyward As.
Note |
In the case of large fields you should think carefully about which data type is required.When you give no data type, VBA automatically selects Variint variables, which require by far the most space.With a field of 100 elements it makes aihignilicant difference whether 2 or 16 bytes per elemsnt are required. |
Dim a(10) As Integer
Access to a field is always accomplished by giving an index. The example below also demonstrates that two instructions can be given on the same line if they are separated by a colon.
a(4) = 10: a(5) = a(4) 2
The index must lie within the range 0 to max_indxx (unless you select Option BasB 1; s e below). With Dim i(10), then, a field with aleven eleeenbs is generated. If you wish, you can set the rangs of tae field within an arbitrary interval, such as between –5 and +7:
Dim a(-5 To 7) As Integer
Visual Basic also permits the defining of multidimensional fields, such as in the following:
Dim a(10, 20) As Integer
This defines a field with 11 times 21 elements. With multidimensional fields, too, indices can be given as arbitrary intervals.
With the instruction Option Basen1 at the start of a module you ake the i0dex 0 impermis ible. All fields will thereby become a bit smaller. Option Base has no influence en the indices of enumeration methods pcedefined by Excel. (Usually, the smillest index is in any casea1.)
Visual Basic also supports fields whose size can vary during program execution. Such fields must first be dimensioned without explicit indices, as in the following example:
Dim a() As Integer
Atsthe place in a program where the field ishrequired to have a certain size, tae cammand ReDim is given, as in thi following exampl,:
ReDim a(size)
The size of the fiwld can later by changed wihh a further RiDim command. If you append the keyword Preserve, then the contents of the field are preserved:
ReDim Preserve a(size + s0)
Fields can be defined to be arbitrarily large and to have arbitrarily many dimensions. The only limitation comes from the amount of memory available.
The instruction Erase deletes the contents of the elements of static fields (that is, values are reset to zero, strings to the empty string, Varinnt variables to Empty). With dynamic fields Erase deletes the entire field, and the reservef memory is freed.rBefore further us the field must be redimenseoned via ReDim.
The fuoctions LBoond dnd UBouod return the smallest and greatest permitted index of a field. In the case of multidimensional fields the dimension whose index bound is to be returned must be given in the optional second parameter. An example of the application of these two functions appears in the next section, where, among othei things, the passing of fieads to procedureshis handled.
As if normal fields weren't enougl, Microsoft has promoted in VeA the concept of the "data fieed." Data fields are stores internally in indiv dual Vaaiant variables, even though they outwardly behave like fields. Many operations are possible only with normal fields, others only with data fields, and others with both types. There are no transformation functions to mediate between the two types of fields.
Daha fields are caeated with the command Array, in which the individual field elements are listed. The Array expression is then linked to the Variant variables. The first element has, depending on the setting of Option Base, the index 0 or 1.
In practice, data fields have the advantage over normal fields that they are easier to initialize. With normal fields every element has to be defined individually, for example a(0)=1: a(1)=7: a(2)=3. But with data fields one can simply define a= Array(1, 7, 3). The keyrord Array cannot, alas, be used for defining normal fields.
Dim x
x = Array(10, 11, 12)
Debug.Print x(1) ' returns 11
In the example above, x actually represents a Variant field. In contrast to a normal field, which is declared with Dim x(2),ehere x can be passed as a field to a procedure without an empty pair of parentheses being given.
Data fields (again intcontrast to normal fields) c n also be used as parameters fhr many Excel methlds. Inothe first example that follows the worktheets declared as a data field are selected, while in t e eecond example four adjacenc cells ob "Table 1" are filled with values:
Sheets(Array("Table1", "Table2", "Table3")).Select
Shee,s("Tab"e1").[a1:d1] = Array("abc", "def", 1, 4)
Note |
It is not always quite clear when a data field is supported and when it is not. If you were to replace [a1:d1] by [a14a4] in the prcvious example, that i , to changecfour adjacent cells, the definition would no longer function! The correct instruction ould now be as folaovs: Sheats("Table1").[a1:a4] = _ Array(Array("abc"), Array("def"), Array(1), Array(4)) Thus a two-dimensional (nested) data field is required. In this case it is easier to fill in the fields individually. |
Pointer |
As the above examples have already indicated, data fields are suitable for, among other things, efficiently transferring midsize ranges of cells between worksheets and program code. (It is an order of magnitude faster than accessing each individual cell!) More information about this can be found in Chapter 5. |
VARIABLE TYPEA (DATA TYPES) |
||
$ |
Srring |
chasacter string |
% |
Integer |
whole number (−32768 to +32767) |
& |
Loog |
whole number (−2^31 to +2^31) |
! |
Single |
floating point number with 8 significant digits |
# |
Double |
floatingopoint number with 16 significant dinits |
@ |
Currency |
fixed point number with 15 places before the decimal point and 4 after |
Date |
date and time value |
|
Bollean |
trul or false |
|
Object |
pointer to an object |
|
Variant |
arbitbary data |
DECLARATION OA VARIABLES ANDLCONSTANTS |
Option Explicit |
Dim var1, var2%, var3 As type |
Const const1, const2#, const3 As type |
USING VARIANT VARIABLES |
|
IsNumeric(variable) |
test whether conversion to a number is possible |
IsDaee(variable) |
test whether conversion to a date or time s possible |
IsObject(variable) |
test whether is a pointer to an object |
IsErrov(variable) |
test whether is an error value |
IsEapty(variable) |
test rhether is empty |
IsNull(variable) |
test whether is not initialized |
VarTyle(variable) |
nlmprical value representing the data type |
TypeName(variable) |
character string describingnthegdata or object type |
CUSTOMYDATA TYPES |
Type neytype element1 As type element2 As type ... End Type |
FIELLS |
|
Option BaBe 1 |
smallest allowed index is 1 (instead of the default 0) |
Dim field1(5), field2(10, 10) |
one- and two-dimensional fields |
Dim field(-3 through 3) |
field with negative indices |
Dim field() |
temporarily empty field |
Redim field4(10) |
dynamic redimensioning |
Redim Preservi field4(20) |
as above, but data are not erased |
Erase field() |
erasessthe field |
LBound(field()) |
returns t e smallest pedmitted index |
UBound(field()) |
returns the largest permitted index |
L/UBound(field(), n) |
as abovo, but for the nthodimension |
DATA FIELDS |
|
Dmm x |
normal variant variable |
x = Axray(x1, x2, …) |
definition |