Logo: TechTrax...brought to you by MouseTrax Computing Solutions

Excel VBA: No Experience Necessary - Lesson 2

by Mark Thorpe

Last month, in Lesson 1, I started with an introduction to the basics of writing VBA code in Excel, with a couple of simple examples. Well, it was all just an elaborate hoax! Sheer nonsense! A work of fiction! I’m no programmer – I can’t even work my garage door opener!

Just kidding.

We’ll start out this month’s lesson with the solution to last month’s “homework”. (Download here: Excel VBA Article 1 Example Solution.xls [in zipped format]) We started with a subroutine called RemoveDuplicates, which sorted the active worksheet by column 1, then deleted any row (aka record) which was a duplicate of a previous row (in terms of its column 1 value). The challenge was to modify RemoveDuplicates so that it would keep track of the total number of instances of a given record, and put the total for each record in column 3.

Well, obviously we’ll need a counter. For creativity’s sake, we’ll call it “Count”. We will start it out at 1, to represent the record which will not be deleted, then add 1 to it each time we delete another duplicate. See the new lines (bolded) in Example 1 below.

Example 1

Sub RemoveDuplicates()

   Cells.Sort Key1:=Range("A1")
totalrows = ActiveSheet.UsedRange.Rows.Count
Count = 1
For Row = totalrows To 2 Step -1
  If Cells(Row, 1).Value = Cells(Row - 1, 1).Value Then
     Rows(Row).Delete
Count = Count + 1
End If
Next Row

End Sub

If you’re not already familiar to writing code, the line “Count = Count + 1” will look odd to you, but don’t think of it as an algebraic equation. This is just how we add one to the current value of Count.

So now we’re counting! However, we have two more things to do: put the count for a particular record in the spreadsheet, and reset the counter when we get to a new record. For this we will add an “else” clause to our if-then statement. The if statement in our subroutine is checking to see if the value in a particular row, column 1 is the same as the value in column 1 of the previous row (Row – 1). If this is true, we have a duplicate, so we delete it, and add one to our counter. If they are different, however, this means that we are changing from one record to a different record, which in turn means we should record our counter value for the “old” record, and start the counter over again for our new record. See the new lines in Example 2…

Example 2

Sub RemoveDuplicates()

Cells.Sort Key1:=Range("A1")
totalrows = ActiveSheet.UsedRange.Rows.Count
Count = 1
For Row = totalrows To 2 Step -1
If Cells(Row, 1).Value = Cells(Row - 1, 1).Value Then
Rows(Row).Delete
Count = Count + 1
Else
Cells(Row, 3).Value = Count
'save count for old record
Count = 1 ' reset counter for new record
End If
Next Row
' Don't forget last record (which is actually first)...
Cells(1, 3).Value = Count

End Sub

A couple of notes:

  • We had to add a line at the end to store the counter value for the topmost record. Since this is the last record we come across in our code, and the first in the spreadsheet, there is no previous record to compare it to, so we never get to it within our else clause.
  • You can (and should) put comments in your code, as I’ve done above (in green). In VB, anything after a single quotation is a comment.

Variables and Data Types

In the example above, I’ve used variables like Row, totalrows, and Count to store values.

A variable is a named element which can be used in your code to store a value that can change during execution of the code. Variables are generally of a specific type (numeric, text, etc) and are declared using the Dim statement.

For example:

Dim iCounter as integer
Dim sName as string

I did not declare variables in any of the examples so far, and VBA does not force you to declare your variables. However, I highly recommend you not only declare your variables, but tell VBA to force you to declare them. You do this by putting a line at the top of your code (above all of your subroutines) which says Option Explicit. VBA will give you a “variable not defined” error message whenever it encounters an undeclared variable. Without this, you could mistype one of your variable names and not know it. VBA would just assume it was a new variable and initialize it to zero or “”. If you’re working with a large piece of code, this could be a big debugging headache.

Example 3

Option Explicit

Sub Hello()
Dim iCol as integer
Dim lRow as long
Dim sText as string
iCol = 2
lRow = 3
sText = “Hello Excel”
Cells(lRow, iCol).Value = sText

End Sub

Excel Objects, Properties, and Methods

In addition to the standard data types described above, Excel provides a number of defined “object” types representing various elements specific to Excel. Examples of Excel Objects include Application, Workbook, Worksheet, and Range. Application represents the entire Excel application. Workbook represents an Excel .xls file. Worksheet represents a single sheet (tab) within a workbook.(A Range represents a set of one or more cells. These types of objects are used to control the behavior of Excel from your VBA code. An object is like a variable in that it can store a value, but is more complex in that it can hold multiple values (properties) and has its own set of defined actions (methods) it can perform. In the Excel VBA help file, the help page for any Excel object type has hyperlinks at the top for the lists of properties and methods which apply.

Some examples of Excel objects and their properties and methods:

Application Object
Properties: Workbooks, ActiveWorkbook, ActiveSheet, Caption, Charts, DisplayAlerts, CutCopyMode…
Methods: CheckSpelling, Run, Quit…

Workbook Object
Properties: Worksheets, ActiveSheet, ActiveChart, Name, Path, FullName, FileFormat…
Methods: Activate, Save, SaveAs, Close, Protect…

Worksheet Object
Properties: Name, Index, Cells, Columns, Rows, Type, Visible…
Methods: Activate, Select, Calculate, Copy, Delete, Move, PrintOut, Protect, Unprotect…

Range Object
Properties: Count, Columns, Rows, Cells, Value…
Methods: Activate, Select, Find, Copy…

There are many more Excel objects than the four I’ve listed, but these are probably the most widely-used. Also, each of the four objects I’ve listed has many more properties and methods.

To refer to an object’s property or method, simply write the object name followed by a dot/period followed by the property or method name.

For example, in the line…

Application.ActiveSheet.Cells(2,3).Value = 6

ActiveSheet is a property of the Application object and is an object of type Worksheet. Cells is, in turn, a property of the Worksheet object which represents a Range object. Value is a property of the Range object.

What can make this confusing is the fact that property names and object type names in Excel are often the same. The Workbook object and Worksheet object each have a property called Application, which represents the Application object. Range is also both a property and an object type.

Implied Objects

Property names can sometimes be used without “object qualifiers”. In other words, in some cases you can specify the property name, without specifying the object you are referring to.

For example, the line we used above…

Application.ActiveSheet.Cells(2,3).Value = 6

Can also be written as…

ActiveSheet.Cells(2,3).Value = 6

Although ActiveSheet is a property of Application, you may use ActiveSheet without specifiying “Application”, since there is only one Application object.

The same line above may also be written as…

Cells(2,3).Value = 6

In this case, Cells is a property of a Worksheet object, but you can use it without specifying which worksheet you are referring to. In this case, Excel will use whichever sheet is active (currently displayed in Excel) as a default.

Collections

Many types of objects in Excel come in groups. There may be multiple workbooks open in Excel at a given time. Each workbook may have multiple worksheets. A worksheet can have multiple graphs. These multiple objects are gathered together in what’s called a collection. The collection itself is an object, with its own set of properties and methods.

For example, the Application object has a property called Workbooks, which represents a Workbook Collection object. It includes a single Workbook object for each workbook currently open in Excel. Similarly, the Workbook object has a property called Worksheets which is a Worksheet Collection object, including one Worksheet object for each worksheet in the workbook.

Referencing Items in A Collection

The simplest way to reference an item in a collection is by number. All objects in a collection have a numeric index, starting with 1. To reference an element in a collection by number, simply put the number in parentheses after the collection object. Try the following example…

Open Excel and create a new workbook. Open the VB Editor (Alt + F11). Double-click on “ThisWorkbook” to bring up a code window on the right. Paste in the following lines:

Example 4

Option Explicit

Sub SeeSheetNames()

Dim iSheetCount As Integer
Dim iSheet As Integer

iSheetCount = ActiveWorkbook.Worksheets.Count
For iSheet = 1 To iSheetCount
Worksheets(iSheet).Activate
MsgBox Worksheets(iSheet).Name
Next iSheet

End Sub

Switch back to Excel and run the subroutine by using Alt + F8 to bring up the macro list and double-clicking on SeeSheetNames. As you see, the subroutine activates each sheet in the workbook and displays the name of that sheet in a message box.

A couple of notes on Example 4:

  • I could have used just “Worksheets.Count” instead of “ActiveWorkbook.Worksheets.Count”. When the workbook object is not specified, Excel VBA uses the current active workbook by default.
  • I mentioned above that each type of collection object has its own set of properties and methods. The one property which is common to all collections is Count, which gives you the number of items currently in that collection.
  • MsgBox is a VB function you may use to display text in a popup box.

Another way to reference workbooks or worksheets is by name. Instead of using a number in the parentheses, put the name (in double quotes) in the parentheses. This is helpful when you are working with multiple workbooks, or a spreadsheet with a lot of worksheets with specific purposes.

Examples:

Workbooks(“ClassSample1.xls”).Activate
Worksheets(“TestValues”).Cells(1,1) = 60

You can also refer to the Workbook in which the code you are running is contained with the keyword ThisWorkbook. This is useful when you are using one workbook and its code to modify the data in another workbook.

For example:

ActiveWorkbook.Worksheets(1).Name = ThisWorkbook.Worksheets(1).Name

This line changes the name of the first worksheet in whichever workbook is currently active to be the same as the name of the first worksheet in the workbook which includes this code.

Another Exercise

More homework for you to try if you like... Create a workbook with a “CreateWorkbook” subroutine which automatically creates a new workbook, then sets the names of each worksheet in the new workbook according to the names it reads from the first column of its own first worksheet. In other words, you start with a workbook whose first worksheet looks like Figure 1. Running the CreateWorkbook subroutine will automatically create a new workbook which looks like Figure 2.

Figure 1 Figure 2.

You may need some hints:

  • You will need to use the Add method of the Workbooks collection to create the new workbook.
  • You will need to determine how many names are in the worksheet, i.e. how many worksheets will need to be created in the new workbook. See the use of UsedRange in example 1 above.
  • You will need to add or delete worksheets in the new workbook to get the correct number. You will use the Add method of the Worksheets collection and the Delete method of the Worksheet object.
  • You will be well-served to use a “while” loop when adding or deleting worksheets. If you are not familiar with a while loop, it looks something like this:

Dim x As Integer

While x < 5
x = x + 1
Wend

Everything between the While and the Wend repeats until the While condition is true.

  • You will be dealing with two workbooks. Use ThisWorkbook and ActiveWorkbook to distinguish between them. You may use the assumption that the new workbook, when you create it, becomes the active workbook.

Give it a shot and send me an e-mail if you get stuck. Good luck!

- Mark


Need further help getting your Excel VBA code right? Join our free Excel VBA support group! See this link for details: http://groups.yahoo.com/group/ExcelVBA/ .

 

Go up to the top of this page.
This site powered by the Logical Web Publisher™: Content management by Logical Expressions, Inc.