In this chapter, you'll learn how to find the objects you need in the applications you're using. We'll build on what you learned in the earlier chapters. You'll start by examining the concepts involved: what objects and collections are, what properties are, and what methods are. You'll then learn how to find the objects, collections, properties, and methods you need to make your code work. To identify these items, you'll use a number of tools you've already read about, including the Object Browser (which you used briefly in Chapter 4, “Creating Code from Scratch in the Visual Basic Editor”) and the VBA online Help resources.
Along the way, this chapter explains how to use Object variables to represent objects in your code.
VBA-enabled applications (and many other modern applications) consist of a number of discrete objects, each with its own characteristics and capabilities.
Building an application out of objects is called object-oriented programming (OOP). In theory, object-oriented programming offers a number of benefits to programmers—for example, the code is said to be easier to build and maintain (update) because you break it down into objects of a manageable size.
Again, in theory object-oriented programs are considered by some experts to be easier to understand than monolithic programs because it's less difficult for most people to grasp the concept of individual objects with associated characteristics and actions than to remember a far longer list of capabilities for the application as a whole.
Figuring out which commands to use to accomplish your programming goals can also be faster thanks to OOP taxonomy. For example, a table in Word is represented by a
object, and a column is represented by a Table
object. The Column
object has a Column
property that sets or returns its width. It's simpler to manage this information when it's broken down into these small pieces than to deal with some more complex command such as Width
or WordTableSetColumnWidth
. Note that this use of OOP is not the same as creating your own objects in your code. Instead, you're employing objects (essentially commands) that are already embedded within the VBA language itself.WordTableGetColumnWidth
A third benefit of object-oriented programming is that the VBA language itself can be extended. The programmer can build custom objects to implement functionality that the language itself didn't originally contain. For example, you can use VBA to build your own objects that do things that the Office applications themselves can't do.
Another, rather different, use for OOP is somewhat clerical: OOP can be of considerable help when a group of programmers are working together on a single program. They can quite easily step on each other's toes in various ways—using an earlier version than the others on the team, changing each other's code without communication, and so on. At the end of this chapter, we'll look at the ways OOP is employed to prevent these problems in team programming. This is perhaps the primary reason to program with OOP.
Objects can—and frequently do—contain other objects. Typically, the objects in an object-oriented application are arranged into a hierarchy called the object model of the application. This hierarchy is intended to make it easier to figure out where—within a large library of objects—you'll find a particular object that you want to use in your macros. It's similar to the way a biography is likely to be found in the library's nonfiction area.
Most VBA host applications, including all the major Office applications, have an
object that represents the application as a whole. The Application
object itself has properties and methods for things that apply to the application as a whole. For example, many applications have a Application
method that exits the application and a Quit
property that controls whether the application is visible or hidden.Visible
In a typical object model, the
object essentially contains all the other objects (and collections—groups—of objects) that make up the application. For example, Excel has an Application
object that represents the Excel application, a Application
object (grouped into the Workbook
collection) that represents a workbook, and a Workbooks
object (grouped into the Worksheet
collection) that represents a worksheet. The Sheets
object is contained within the Workbook
object because you normally need to have the Excel application open to work with an Excel workbook.Application
In turn, the
object is contained within the Worksheet
object because you need to have an Excel workbook open to use a worksheet. Walking further down the object model, the Workbook
object contains assorted other objects, including Worksheet
objects that represent the individual rows in the worksheet, Row
objects that represent columns in the worksheet, and Column
objects that represent ranges of cells. And these objects in turn contain further objects.Range
To get to an object, you typically walk down through the hierarchy of the object model until you reach the object you're looking for.
To get to a
object in Excel, for example, you would go through the Range
object to the Application
object, through the Workbook
object to the appropriate Workbook
object, and then finally to the Sheet
object. The following statement shows how to select the range A1 in the first worksheet in the first open workbook (more on this in a minute):Range
Application.Workbooks(1).Sheets(1).Range("A1").Select
The
object, however, is optional and is usually left out of code. Why? Because you'd have to go through the Application
object to get to pretty much anything in the application, most applications expose (make available to you) a number of creatable objects. Creatable merely means that you can access something without having to type the word Application
in your code. It's assumed. This is similar to the fact that you don't have to include the word Earth when addressing an envelope. There's only that one possibility (so far).Application
These creatable objects are usually the most-used objects for the application, and, by going through them, you can access most of the other objects without having to refer to the
object. For example, Excel exposes the Application
collection as a creatable object, so you can use the following statement, which doesn't require that you type in Workbooks
. See the alternative example a couple of paragraphs earlier in this chapter.Application
Workbooks(1).Sheets(1).Range("A1").Select
Any object can have properties and methods. The next sections discuss these items in detail.
In VBA, a property is an attribute or characteristic of an object. Think of it as a quality of an object, such as its color. Most objects have multiple properties that specify each aspect of that object.
Each property has a specific data type for the information it stores. For example, the objects that represent files (such as documents, workbooks, or presentations) typically have a Boolean property named
that stores a value denoting whether all changes in the object have been saved (a value of Saved
) or not (a value of True
). These two values encompass the entire range of possibilities for the saved status of the object: it can either contain unsaved changes or not contain unsaved changes. There is no third state. A Boolean data type can, therefore, be used because that type has only two possible values.False
Similarly, most objects that represent files have a
property that contains the name of the file in question. The Name
property contains a String data type because it needs to contain text. That text can be just about anything, limited only by the 255-character path that Windows permits for files and by certain characters—such as colons and pipe (|) characters—that Windows forbids in filenames.Name
To work with a property, you get (fetch or return) it to find out its current value or set (change) it to a value of your choosing. Many properties are read/write, meaning that you can both get and set their values, but some properties are read-only, meaning that you can view their values but not change them.
The
property is read/write for most applications, so you can set it. This means that you can tell the application that a file contains unsaved changes when it really doesn't or that it contains no unsaved changes when it actually has some. (Changing the Saved
property can be useful when you're manipulating a file without the user's knowledge.) However, the Saved
property of a file object is read-only—you'll typically set the name by issuing a Name
command, after which you cannot change the name from within the application while the file is open. Therefore, you can get (read, return, or fetch) the Save As
property but not set it. You'll also encounter some write-only properties, properties that you can set but not get.Name
When an object contains another object, or contains a collection, it typically has a property that you call (invoke) to return the contained object or collection. For example, the Word
object includes a Document
property that returns the PageSetup
object for the document (the PageSetup
object contains settings such as paper size, orientation, lines per page, and margins for the document) and a PageSetup
property that you call to return the Tables
collection. Here's how you can call the Tables
object (which is contained in the PageSetup
object):Document
Sub GetLinesPage()
Dim sngLinesPerPage As Single
sngLinesPerPage = ActiveDocument.PageSetup.LinesPage
MsgBox sngLinesPerPage
End Sub
Each object of the same type has the same set of properties but stores its own particular values for them. For example, if you're running PowerPoint and have three
objects open, each has its own Presentation
property. The value in each Name
property is specific to each Name
object. In other words, the value in a property in one object has nothing to do with the value in that property in another object: Each object is independent of the other objects.Presentation
A method is an action that an object can perform … a capability. For example, the
object in various applications has a Document
method that saves the document. You can use the Save
method on different Save
objects—Document
saves the first Documents(1).Save
object in the Document
collection, and Documents
saves the second Documents(2).Save
object—but the Document
method does the same thing in each case.Save
An object can have one or more methods associated with it. Some objects have several dozen methods to implement all the functionality they offer.
The
method is very common. It appears in many applications' objects, as do other methods, such as Save
(which saves the file with a different name, location, or both) and SaveAs
(which closes the file).Close
Other methods are unique to each application. For example, the
object in PowerPoint has an Presentation
method that applies a baseline (consisting either of the active presentation or of a specified presentation file) that enables you to track changes for a merge. The AddBaseline
object in Word has no Document
method, but it has an AddBaseline
method that accepts all revisions in the document. PowerPoint in turn doesn't have an AcceptAllRevisions
method.AcceptAllRevisions
Just as methods such as
are common to multiple applications, some methods are found in more than one object. For example, the Save
method is associated with many different objects. As its name suggests, the Delete
method usually deletes the specified object. However, other implementations of the Delete
method behave somewhat differently, depending on the object with which they're working. Therefore, even if you're familiar with a method from using it with one object, you need to make sure that it will have the effect you expect when you use it with another object.Delete
Some methods take no arguments. Other methods take one or more arguments (to supply necessary information). Just as with built-in VBA functions such as
, some arguments are required, while others are optional.MsgBox
When a method applies to multiple objects, it may have different syntax for different objects. Again, even if you're familiar with a method, you need to know exactly what it does with the object for which you're planning to use it.
To use a method, you access it through the object involved. For example, to close the
object, which represents the active presentation in PowerPoint, you use the ActivePresentation
method. However, you must specify the Close
object, like this:ActivePresentation
ActivePresentation.Close
When an object contains more than one object of the same type, the contained set of objects is said to be grouped into a collection.
For example, Word uses
objects, which are grouped into the Document
collection. PowerPoint has a Documents
collection for Presentations
objects, and Excel has the Presentation
collection.Workbooks
As in these examples, the names of most collections are simply the plural of the inner, contained objects. There are some exceptions, such as the
collection in Excel that contains the Sheets
objects. But by and large the names of most collections are easy to derive from the name of the objects they contain—and vice versa.Worksheet
A collection—taken as a whole—is itself an object, too, and can have its own properties and methods (which will apply to the collection as a unit). For example, many collections have a
property that tells you how many objects are in the collection. This next example tells you how many documents are in the Count
collection:Documents
Sub GetDocCount()
Dim lngCount As Long
lngCount = Documents.Count
MsgBox lngCount
End Sub
Collections tend to have fewer properties and methods than individual objects. Most collections have an
method for adding another object to the collection. Some collections, however, are read-only and do not have an Add
method. Most collections have an Add
property (the default property) for accessing an item within the collection.Item
Most collections in VBA have a core group of properties listed in Table 8.1.
TABLE 8.1: Core properties for collections in VBA
PROPERTY | EXPLANATION |
|
A read-only property that returns the application associated with the object or collection—the root of the hierarchy for the document. For example, the property for objects in PowerPoint returns . |
|
A read-only Long property that returns the number of items in the collection—for example, the number of objects in the collection in a PowerPoint slide. |
|
In Microsoft applications, a read-only Long property that returns a 32-bit integer indicating the application used to create the object or collection. |
|
A read-only property that returns a specified member of the collection. is the default property of every collection, which means that you seldom need to specify it. |
|
In Microsoft applications, a read-only String property that returns the parent object for the object or collection. The parent object is the object that contains the object in question; the contained object is the child object. For example, a object is a child of the collection. |
To work with an object in a collection, you identify the object within the collection either by its name or by its position in the collection. For example, the following statement returns the first
object in the Document
collection and displays its Documents
property in a message box:Name
MsgBox Documents(1).Name
You can optionally use the
property to return an object from the collection, but because Item
is the default property of a collection, you don't need to specify it in your code. It's assumed.Item
The following two statements return the same value, so there's no advantage to using the
method:Item
strName = Documents(1).Name
strName = Documents.Item(1).Name
To create a new object in a collection, you add an object to the collection. In many cases, you use the
method to do so. For example, the following statement creates a new Add
object in Word:Document
Documents.Add
The Visual Basic Editor provides a number of tools for finding information about objects you want to work with:
The following sections show you how to use these tools to find objects.
If you're using a Microsoft application, chances are that the easiest way to figure out what objects you need to use is to run the Macro Recorder and record a quick macro using the tools or menu items that interest you. While you perform various actions in the application, the Macro Recorder creates code that you can then open in the Visual Basic Editor, examine, and modify if necessary.
In spite of its advantages, the Macro Recorder does have two drawbacks:
Let's say you're working in Excel and want to create some macro code that performs an action on a specified workbook in the
collection rather than on the currently active workbook. With the Macro Recorder, you can record only actions performed on the active workbook. (This is the case because the Macro Recorder can record only those actions you can perform interactively in Excel, and you can't work interactively with any workbook other than the active one. The same thing is true for Word documents.)Workbooks
Here's another example: Some Ribbon actions are not recorded. In Word, clicking the Review ➢ Show Markup Formatting feature to deselect it results in no recorded code. To put that behavior into a macro, you would need to write the following code in the Editor yourself:
ActiveWindow.View.ShowFormatChanges = False
You saw an example of the second problem in Chapter 4. Here's another example. This time we'll record a macro to create an AutoCorrect entry. Let's say that you often have to type the word references in your job—dozens of times every day. You can speed up your work by merely typing reffs (or some other abbreviation of your choice). Then Word will automatically replace reffs with references as you type. Here's how to create this macro:
This displays the Record Macro dialog box.
Add_Item_to_AutoCorrect
entry, and click the Edit button to open the macro in the Visual Basic Editor.The code should look like this:
Sub Add_Item_to_AutoCorrect()
'
' Add_Item_to_AutoCorrect Macro
' Change reffs to references
'
AutoCorrect.Entries.Add Name:="reffs", Value:="references"
With Options
.AutoFormatAsYouTypeApplyHeadings = False
.AutoFormatAsYouTypeApplyBorders = True
.AutoFormatAsYouTypeApplyBulletedLists = True
.AutoFormatAsYouTypeApplyNumberedLists = True
.AutoFormatAsYouTypeApplyTables = True
.AutoFormatAsYouTypeReplaceQuotes = True
.AutoFormatAsYouTypeReplaceSymbols = True
.AutoFormatAsYouTypeReplaceOrdinals = True
.AutoFormatAsYouTypeReplaceFractions = True
.AutoFormatAsYouTypeReplacePlainTextEmphasis = False
.AutoFormatAsYouTypeReplaceHyperlinks = True
.AutoFormatAsYouTypeFormatListItemBeginning = True
.AutoFormatAsYouTypeDefineStyles = False
.TabIndentKey = True
End With
With AutoCorrect
.CorrectInitialCaps = True
.CorrectSentenceCaps = True
.CorrectDays = True
.CorrectCapsLock = True
.ReplaceText = True
.ReplaceTextFromSpellingChecker = True
.CorrectKeyboardSetting = False
.DisplayAutoCorrectOptions = True
.CorrectTableCells = True
End With
With OMathAutoCorrect
.UseOutsideOMath = False
.ReplaceText = True
End With
With Options
.AutoFormatApplyHeadings = True
.AutoFormatApplyLists = True
.AutoFormatApplyBulletedLists = True
.AutoFormatApplyOtherParas = True
.AutoFormatReplaceQuotes = True
.AutoFormatReplaceSymbols = True
.AutoFormatReplaceOrdinals = True
.AutoFormatReplaceFractions = True
.AutoFormatReplacePlainTextEmphasis = True
.AutoFormatReplaceHyperlinks = True
.AutoFormatPreserveStyles = True
.AutoFormatPlainTextWordMail = True
End With
Options.LabelSmartTags = False
End Sub
Here, the Recorder has created dozens of lines of unnecessary code. The only statement you actually need to accomplish your task is this:
AutoCorrect.Entries.Add Name:="reffs", Value:="references"
This line shows you that to add an AutoCorrect entry, you need to work with the
collection object in the Entries
object. You use the AutoCorrect
method on the Add
collection to add an AutoCorrect entry to the list.Entries
All the other lines of code specifying the status of various options are unnecessary because you are not interested in changing any of them in this macro. By removing these extraneous lines from this recorded macro, you can reduce it to just the single line it needs to contain (together with the comment lines, which you can also remove if you want):
Sub Add_Item_to_AutoCorrect()
'
' Add_Item_to_AutoCorrect Macro
' Change reffs to references
'
AutoCorrect.Entries.Add Name:="reffs",Value:="references"
End Sub
You used the Recorder to see the correct syntax for adding an entry to the AutoCorrect feature. There's no point to leaving in lines of code unrelated to your purposes. What's more, such extraneous code would make it harder at some future date to read and understand the macro's purpose.
Worst of all, these extra lines can set properties to conditions that you, or someone else using this macro, might not want. Let's say you run this macro in the future and you are working in a document that must not have any bullet symbols in it. You've clicked the File tab on the Ribbon, chosen File ➢ Options ➢ Proofing ➢ AutoCorrect Options ➢ AutoFormat As You Type, and turned off bullets. However, when you run this macro, bullets are turned back on by this unneeded line in the code:
.AutoFormatAsYouTypeApplyBulletedLists = True
In spite of its limitations, the Macro Recorder does often provide quick access to the objects you need to work with, and you can always modify the resulting code in the Visual Basic Editor. What's more, the code that the Recorder generates is, if nothing else, guaranteed to execute without bugs.
For many programmers, the primary tool for writing code for objects is the Object Browser, which you used briefly in Chapter 4. In the following sections, you'll get to know the Object Browser better and learn to use it to find the information you need about objects. To see the Object Browser, press F2 in the Editor.
The Object Browser provides the following information about both built-in objects and custom objects you create:
Figure 8.1 shows the components of the Object Browser.
Here's what the different elements of the Object Browser do:
The Object Browser uses different icons to indicate the various types of objects that it lists. Figure 8.1 shows several icons; Table 8.2 shows the full range of icons and what they represent.
TABLE 8.2: Object Browser icons
ICON | MEANING |
Property | |
User-defined type | |
Method | |
Global | |
Constant | |
Library | |
Module | |
Project | |
Event | |
Built-in keyword or type | |
Class | |
Enum (enumeration) |
A blue dot in the upper-left corner of a Property icon or a Method icon indicates that that property or method is the default.
The default object libraries are sufficient for most typical macros, so you generally need not worry about adding any specialized libraries. If you get into some kinds of advanced macro programming, however, you will need to add other libraries (you'll modify the Ribbon in Chapter 31, “Programming the Office 2019 Ribbon,” and to do that you do have to add a special library). You can add and remove object libraries by choosing Tools ⇨ References in the Editor and using the References dialog box to make your selections:
When you start the Visual Basic Editor, it automatically loads the object libraries required for using VBA and user forms with the host application. You don't have to change this set of object libraries until you need to access objects contained in other libraries. For example, if you create a procedure in Word that needs to employ a feature found in Excel, you'll have to add to Word's VBA Editor a reference to an Excel object library to make Excel's objects available.
You can adjust the priority (or order of precedence) of different references by adjusting the order in which the references appear in the References dialog box. The priority of references matters when you use in your code an object that's listed in more than one reference: VBA checks the References list to determine the order of the references that contain that object name and uses the first one unless specifically told to do otherwise by use of an unambiguous name.
To add or remove object libraries, follow these steps:
You should find a reference for an object library for each application that supports automation and is installed on your computer. Automation, in this context, means that an application permits the automation of tasks (in other words, macros). Another way to put this is an application that supports automation exposes its objects, meaning that the application makes its objects available to programmers.
The references that are in use appear together at the top of the Available References list box, not in alphabetical order (in order of precedence, as described earlier in this chapter).
Usually, you'll want to keep Visual Basic for Applications and the object library of the application you're working with at the top of your list.
To browse the objects available to a project, follow these steps:
Once you've selected the class, member, or project, you can do the following things with it:
Alternatively, right-click the object in the Members Of list and choose View Definition from the context menu. The View Definition button and the View Definition command are enabled (available, undimmed) only for objects that contain code, such as procedures and user forms that you've created.
VBA's online Help system provides another easy way to access the details of the objects you want to utilize. The Help files provide a hyperlinked reference to all the objects, methods, and properties in VBA, including graphics that show how the objects are related to each other, and plenty of code samples to show you the correct syntax.
The quickest way to access VBA Help is to press the F1 key while working in the Visual Basic Editor.
F1 works two different ways. Press F1 with the cursor (the blinking vertical line) on a blank line in the Code window, and you're taken to the VBA portal shown in Figure 8.3.
However, press F1 with the cursor on a language keyword in your code, such as
or Variant
, and you're taken to a Help page with specific information about that particular keyword.InputBox
First, try clicking a blank line in your Code window, and then press F1. Your browser opens a generic Office website like the one shown in Figure 8.3.
Take some time to familiarize yourself with the various useful links on this page. While we're on the subject of resources, also visit here:
https://stackoverflow.com/questions/tagged/vba
This website is an excellent place to search for answers, or post questions. And there are also quite a few code samples, too.
The second way to use F1 takes you directly to the Help page for the keyword that interests you. If you want to see how to manipulate the active window, for example, just type
into the Editor's Code window, and then, with the blinking insertion cursor somewhere in that word, press F1. See Figure 8.4.activewindow
After you press F1 on the
command, as shown in Figure 8.4, the Help page for this command opens, as you can see in Figure 8.5.activewindow
Notice in Figure 8.5 that it's dated 2017. That simply means that this portal page's links are still valid and haven't needed revision since 2017.
Apart from the regular Help information you'll find in the Help pages online, here are a few additional ways to find help:
These two options open different entrees into the Help system, from which you can drill down until you locate the explanations or code samples you're after. (Note that although the first option listed displays F1, you are not taken to the same web page you get when actually pressing F1.)
You've already used the Auto List Members feature a couple of times in the previous chapters. To recap, in VBA code—as with most other programming languages—objects and their members (properties and methods) are separated by periods. This punctuation helps you see the relationships between parent objects, child objects, and, at the end of the line, the members. Notice the two periods in this code:
sngLinesPerPage = ActiveDocument.PageSetup.LinesPage
When you're entering a statement in the Visual Basic Editor and you type the period, the Auto List Members feature displays a list of properties and methods appropriate to the object. (If necessary, turn this feature on in the Visual Basic Editor by choosing Tools ➢ Options, and then selecting the Auto List Members check box.)
Technically, there's a distinction between Auto List Members and a somewhat similar List Properties/Methods feature. The former feature is triggered by typing a period (.) following the name of an object in a line of code. The latter is triggered by pressing Ctl+J or by right-clicking the name of an object in a line of code and choosing List Properties/Methods from the menu that appears. Of the two, I find Auto List Members more useful.
The Auto List Members feature provides a quick way of completing statements, but you need to know which object you should work with before you can work with its members. Sometimes using this feature is a bit like finding your way through a maze and being given detailed directions that end with the phrase, “But you can't get there from here.”
Once you know the object from which to start, though, you can easily find the property or method you need. For example, to put together the statement
(to close the first document in the Application.Documents(1).Close
collection in Word), you could work as follows:Documents
Sub
and End
Sub
statements). Create a new procedure if necessary.Application
object.Documents
item in the Auto List Members list:
The latter method is shown in Figure 8.7, which uses Word.
Documents
.
When you type this period, the Auto List Members feature displays the list of properties and methods available to a
object. Note that without the Document
, you're working with the documents collection, but as soon as you add the (1)
, you're then working with a specific document, namely the first one in the collection.(1)
Close
method in the Auto List Members list by scrolling to it with the mouse or with the down-arrow key.As you learned in Chapter 6, “Working with Variables, Constants, and Enumerations,” one of the data types available for variables in VBA is the Object type. You use an Object variable to represent an object in your code: Instead of referring to the object directly, you can employ the Object variable to access or manipulate the object it represents.
Here's one major benefit of this approach: Using Object variables makes your code easier to read. It's simpler to see which object a section of code is working with, especially when you're working with multiple objects in the same section of code. What's more, Object variables are often a necessity when you need to manipulate collections of objects. Plus, you can give descriptive names to these variables that are easily understood.
For example, say you create a procedure that manipulates the three open workbooks in Excel, copying a range of cells from one to the other two. If you have only those three workbooks open, you'll be able to refer to them directly as
, Workbooks(1)
, and Workbooks(2)
, respectively, because they'll occupy the first (and only) three slots in the Workbooks(3)
collection.Workbooks
But if your procedure changes the order of the workbooks, closes one or more workbooks, or creates one or more new workbooks, things rapidly get confusing. If, however, you've created Object variables (named, say,
, xlWorkbook1
, and xlWorkbook2
) to refer to those specific workbooks, it will be much easier to keep them straight. This is because no matter which workbook moves to first position in the xlWorkbook3
collection, you'll be able to refer to the object represented by the Object variable Workbooks
and know that you'll be accessing the workbook you're after. In other words, when you create Object variables, you get to name them, using words that are more easily understood than index numbers. More important, once it's named, an Object variable's name does not change. Index numbers can change.xlWorkbook1
To create an Object variable, you declare it in almost exactly the same way as you declare any other variable, using a
, Dim
, or Private
statement. However, you specify the type Public
. For example, the following statement declares the Object variable As Object
:objMyObject
Dim objMyObject As Object
As usual when using the
statement, if you use this declaration within a procedure, it creates a variable with local scope. If you use it in the declarations section at the top of a code sheet, it creates a variable with module-level private scope. Similarly, the Dim
and Private
keywords create module-level private and public Object variables, respectively.Public
Once you've declared the Object variable, you can assign an object to it. (Assigning objects works a bit differently from the way you use just an equal sign to assign a value to an ordinary variable.) To assign an object to an Object variable, you use a
statement. The syntax for a Set
statement is as follows:Set
Set objectvariable = {[New] expression|Nothing}
Here's how that syntax breaks down:
Objectvariable
is the name of the Object variable to which you're assigning the object.New
is an optional keyword that you can use to implicitly create a new object of the specified class. However, usually it's better to create objects explicitly and then assign them to Object variables rather than use New
to create them implicitly.expression
is a required expression that specifies or returns the object you want to assign to the Object variable.Nothing
is an optional keyword that you assign to an existing Object variable to obliterate its contents and release the memory they occupied.For example, the following statements declare the Object variable
and assign to it the active workbook in Excel:objMyObject
Dim objMyObject As Object
Set objMyObject = ActiveWorkbook
The following statement uses the
keyword to release the memory occupied by the Nothing
Object variable:objMyObject
Set objMyObject = Nothing
What's different about declaring an Object variable versus declaring other types of variables is that not only can you declare the Object variable as being of the type
and then use the Object
command, but you can also specify which type of object it is. Let's stop for a moment to consider what this means. Say that you want an Object variable that will always represent a Set
object. You can declare it as being of the Workbook data type. The following statement declares the Object variable Workbook
as being of the Workbook data type:xlWorkbook1
Dim xlWorkbook1 As Workbook
Strongly associating a type with an Object variable like this has a couple of advantages. First, once you've strongly typed (as it's called) the Object variable, the Visual Basic Editor can provide you with full assistance for the Object variable, just as if you were dealing with the object directly. For example, once you've created that Object variable
of the xlWorkbook1
object type, the Visual Basic Editor displays the Auto List Members drop-down list when you type that Object variable's name followed by a period, as shown in Figure 8.8.Workbook
Second, when you strongly type an Object variable, you make it a bit harder to get things wrong in your code. If you try to assign the wrong type of object to a strongly typed Object variable, VBA views that as an error, and informs you of it. Say that you create a
Object variable in Excel, as in the first of the following two statements. But then you attempt to assign it to a Worksheet
object, as in the second statement:Workbook
Dim wksSheet1 As Worksheet
Set wksSheet1 = ActiveWorkbook
VBA displays a “Type Mismatch” error message when you execute that code—as well it should.
Finding out at this testing stage that you've created a problem is usually preferable to finding out later (for example, when later in your code you manipulate the
object and discover it doesn't behave as you expect it to). Remember that debugging is often a matter of figuring out where in your code the problem occurs. Not what the problem is.wksSheet1
The main argument for not strongly typing an Object variable is that you might not be sure ahead of time (while writing the code) what kind of object that variable will eventually reference during execution or if the kind of object it will store may vary from one execution of the code to another. (If either is the case, your code will need to be flexible enough to accommodate objects of different types in the same Object variable.) Usually, though, you'll want to strongly type all your Object variables.
If you're not sure which object type to use for an Object variable, start by declaring the Object variable as being of the Object data type. Then run through the code a couple of times with the Locals window (View ➢ Locals Window) displayed, and note the data type that VBA assigns to the Object variable. For example, if you press F8 repeatedly to step through the following statements in a Visual Basic Editor session hosted by Excel, the readout in the Locals window at first identifies the Object variable
only as wks
.Object
That's not too useful. However, press F8 again to execute the
command, and you see loads of information (press the + icon next to Set
). You now see wks
(as shown on the right in Figure 8.9) when executing the second statement assigns the first sheet in the active workbook to it. You also can see all the members, their current values, and their type.Object/Sheet1
Dim wks As Object
Set wks = ActiveWorkbook.Sheets(1)
VBA is used by individual programmers as well as by programming teams. OOP can offer some special advantages when you are trying to manage a group of programmers working together on a large, complex VBA solution.
OOP can help people avoid stepping on each other's toes—duplicating global variable names, creating version problems, and so on. These nasty side effects can be caused when each programmer works with their latest version of the overall project. How can these source code variations be reconciled? Who arbitrates what gets into the final, collective project?
Group programming needs management, and OOP, among its other benefits, assists in avoiding chaos when a team needs to work together on a common goal.
One feature of OOP is encapsulation. This means that an object is self-contained and sealed off. It's like a so-called “black box” that you plug into your video system to improve the picture. You don't open the box. Nobody is supposed to modify the innards. You just add it to your system and can twist maybe some buttons to adjust whatever parameters the creator of the box made available to you.
As an example, say that the boss wants all documents from now on to emphasize the company's name. You give Sandra the task of creating an object that is supposed to italicize and capitalize all references to ACME WINDOWORKS in all company documents. You ask Joe to create an object that ensures that any use of the company name is displayed in green rather than the normal black letters. (In reality, you would likely want to code these simple manipulations into functions—see Chapter 10, “Creating Your Own Functions,”—rather than objects. Objects often perform multiple related jobs rather than a single, simple job like turning something green, but this is just an example, so we'll keep it simple here.)
When this code is encapsulated into sealed-off objects, nobody has to worry that Sandra and Joe might use the same variable names or otherwise interfere with each other's code. Instead, within their totally separate, sealed-off objects, they can go ahead and write code as they please. This is because the scope of the code is local to the object, and also, neither Joe nor Sandra can view, much less modify, each other's code. Variables in this situation are entirely local. And proper messaging between these objects ensures stability, upgradability, and harmony in the workplace:
ItalAndCap
object.As a result, you avoid a lot of problems if people are working on individual tasks with the assurance that nobody else will be able to mess with their code or accidentally interact with it in some unpredictable way. Also, it's easier to track down bugs because each job is isolated from other jobs—and if the company name is turning green only half the time, you can tell Joe to take another look at his object. No need to involve Sandra.
It's true that over the years some elements of OOP theory have grown quite arcane and abstract. OOP can be, in the upper reaches of universities, a terribly complex subject of study. In fact, they say that, like quantum mechanics, advanced OOP theory is fully understood by only 12 people in the world—and they're fooling themselves.
Nonetheless, if you are in charge of a team that's responsible for building a large application for Office, take some time to employ OOP's clerical features. Each individual programmer will be responsible for how their object works. The other programmers can merely use that object without worrying about debugging it. They are not even allowed to see its internal code. Consider the objects that are built into VBA itself, such as Word's
object. It was written by somebody at Microsoft. You can put this object in your code and ask it to do things for you, such as move the cursor one word to the left:Selection
Selection.MoveLeft Unit:=wdWord, Count:=1
But you never see the actual code within the
object that moves the cursor. You aren't allowed to modify it, and its code does not interact with your code's variables or cause other unwanted side effects. In other words, the built-in VBA objects are encapsulated—usable as black boxes, and sealed off.Selection
To create your own encapsulated objects in VBA, you can add class modules to a project, which are distinct from regular code modules. You'll see how to do this in Chapter 16, “Building Modular Code and Using Classes.”
Application
object. You go through this object to get to other objects that are lower in the hierarchy.
Application
object when referencing it in code. What are creatable objects?Documents
collection of Document
objects.
Document
object?