Values and References in VBA

April 25, 2013 in VBA

Visual Basic for Applications has a unique system of data types. One of the most fundamentally important concepts to understand is the difference between values and references in VBA, but it is very difficult to find clear explanations of this concept. I attempt to present one here. In this article I describe the difference between values and references, and between value types and reference types. In another article I will describe how the ByRef and ByVal keywords work.

Synonyms

When trying to make sense of this article in comparison with other articles and documentation, keep in mind that other sources sometimes use different terms:

  • Value types are sometimes called primitive or simple types
  • Reference types are sometimes called object types.

Values and value types

A value is piece of literal information, like the number 8 or the string “Hello”. Value type variables contain literal values; a variable of type Integer could contain the number 8, and a variable of type String could contain the value “Hello”. The formal way of saying this is that value types use value semantics, which means: “Whenever I type the name of the variable, I really mean the value of the variable”. This might seem rather obvious.

Consider the following example:

Dim int1 As Integer, int2 As Integer
int1 = 17
int2 = int1
Debug.Print "int1 ="; int1; ", int2 ="; int2
int2 = 2
Debug.Print "int1 ="; int1; ", int2 ="; int2

First we assign the value 17 to the variable called “int1″. Then we assign int1 to int2. We obviously mean to copy the value of int1 (which is 17) to int2. This is value semantics in action. As a result, the first Debug.Print call shows that both int1 and int2 have the value of 17. Next, we assign the literal value 2 to the variable int2. The second Debug.Print call shows that int1 still has a value of 17 while int2 now has a value of 2.

This probably all seems blindingly obvious. The reason it matters is that it is completely different for references and reference types, as described next.

References and reference types

A reference is an indirect way to refer to something. The title of a book or the postal address of a building are references. They allow us to refer to big or complicated chunks of information with a small shorthand label. I can refer to the book “Moby Dick” just by those 9 characters; I don’t have to recite the entire contents of the book. At the same time “Moby Dick” is not the content itself, but only a reference. If I want to read the famous first sentence of the book I will have to use my reference (the title) at a library or bookstore to look up the actual content.

It’s the same for references and reference type variables in VBA. They don’t contain the content of the target. Instead they contain a reference to the target. Reference types use reference semantics, which means: “When I type the name of the variable, I really mean a reference to something else.”

Consider a worksheet in Excel. Its literal content is all the values, formulas, and formatting of all the cells in the sheet. But if we declare a variable of type Worksheet in Excel and then assign the first worksheet in the current workbook to that variable we definitely do not mean to copy the entire content of the worksheet to the variable. Instead, we mean only to copy the reference to the worksheet. If we then assign the first variable to another variable of type Worksheet we again copy only the reference to the worksheet, not the entire contents of the worksheet.

Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = ThisWorkbook.Worksheets(1)
Set ws2 = ws1

Two references with the same target point to the same information. As a result, a change made to the target via one reference will be visible through all other references to that same target. In the following example all three variables are set to be references to the same worksheet. When we then change the name of the worksheet via just one of the variables, that change is immediately visible through all three variables.

Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet
Set ws1 = ThisWorkbook.Worksheets(1)
Set ws2 = ws1
Set ws3 = ws2
ws3.Name = "A new name"
Debug.Print "ws1.Name = "; ws1.Name; _
          ", ws2.Name = "; ws2.Name; _
          ", ws3.Name = "; ws3.Name;
The value of a reference

In my opening analogy I explained how I can use the title “Moby Dick” as a reference to the actual book. The content of the reference itself (the title) is the 9 character string “Moby Dick”. So what is the actual content of a reference in VBA? The answer is that it is nothing intelligible to a human, because it doesn’t need to be. It is not as simple as a memory address (a pointer), either. In fact the actual implementation of a reference is a complicated affair, but if you’re really curious you can get a taste from the following article on MSDN: Managing Object Lifetimes Through Reference Counting.

Further differences between value and reference types

Assignment and binding in VBA

In VBA, the difference between value types and reference types is made explicit by requiring the keyword Set when assigning a reference. In addition, you will often see assigning a reference referred to as “binding”.

Dim myInt As Integer, myWs As Worksheet
' Assigning a value to a value-type variable:
myInt = 3
' Assigning (or "binding") a reference to a reference-type variable:
Set myWs = ThisWorkbook.Worksheets(1)
All reference types are Objects in VBA

In VBA reference types are called Objects. Any reference type passed to the VarType function will return the vbObject constant, any reference type passed to the IsObject function will return True, and any reference can be assigned to a variable declared simply as type Object.

Dim db As Database, td As TableDef, c As Collection, obj As Object
Dim vType As VbVarType, bResult As Boolean
vType = VarType(db)     ' vbObject
vType = VarType(td)     ' vbObject
vType = VarType(c)      ' vbObject
vType = VarType(obj)    ' vbObject
bResult = IsObject(db)  ' True
bResult = IsObject(td)  ' True
bResult = IsObject(c)   ' True
bResult = IsObject(obj) ' True
Set obj = db            ' Ok
Set obj = td            ' Ok
Set obj = c             ' Ok
Everything else is a value type

All the other built-in data types in VBA are value types1. In addition, user defined types declared with the Type keyword, all enums, and all arrays are value types.

Got that? Arrays are value types!

The fundamental impact is that assigning an array copies the entire contents of the array. It also means that it is very difficult (or impossible) to work with array-typed members of objects or collections. This will be described in detail in a future post.

Conclusion

There are two fundamental groups of data types in VBA: Values and references. Data types that contain values are called value types. Data types that contain references are called reference types, object types, or simply objects. All reference types are compatible with the Object type. Unlike many other languages, arrays in VBA are value types, which means assignment causes the entire source array to be copied.

1 Not including the Variant type. The Variant type is not really a type itself, though, but a wrapper that can contain any of the other types.