C H A P T E R 4 | Microsoft Office 97/Visual Basic Programmer's Guide |
Microsoft Excel Objects |
Most properties of the Microsoft Excel Application object control the appearance of the application window or the global behavior of the application. For example, the value of the DisplayFormulaBar property is True if the formula bar is visible, and the value of the ScreenUpdating property is False if screen updating is turned off.
In addition, properties of the Application object provide access to objects lower in the object hierarchy, such as the Windows collection (representing all currently open windows) and the Workbooks collection (representing all currently open workbooks). You use these properties, sometimes called accessors, to move down the object hierarchy from the toplevel Application object to objects lower in the hierarchy (such as the Workbook, Worksheet, and Range objects). For more information about navigating through an object model, see Chapter 2, "Understanding Object Models."
Some methods and properties that apply to the Application object also apply to objects lower in the object hierarchy. Using these properties or methods at the Application level usually changes all open workbooks or sheets. For example, the Calculate method applies to the Application, Workbook, and Worksheet objects. Using Application.Calculate recalculates all worksheets in all open workbooks, whereas using this method on the Workbook or Worksheet object provides greater control.
When you open or save a file in Microsoft Excel, you're actually opening and saving a workbook. In Visual Basic, the methods for manipulating files are methods of the Workbook object or the Workbooks collection.
Opening Workbooks
When you open a workbook, you use the Open method. The
Open method always applies to the Workbooks collection,
which you return using the Workbooks property. The following
code opens the file Book1.xls (in the current folder) and then
displays the value that's in cell A1 on the first worksheet in
the workbook.
Notice that the return value of the Open method is a Workbook
object that refers to the workbook that was just opened.
The file name in this example doesn't contain a path; therefore,
the file is assumed to be in the current folder. This is guaranteed
to cause a runtime error, because as soon as the user changes
the current folder, Visual Basic can no longer find the file.
There are two relatively safe places to store a workbook you want
to open programmatically. One place is the folder that contains
the executable file for Microsoft Excel. The other place is the
Library folder, which is created automatically during setup; this
folder is one level down from the folder that contains the executable
file.
If you want to open a workbook that's saved in the folder that
contains the executable file, you can use the Path property
to return a string that specifies the folder. The PathSeparator
property returns the correct separator character for the current
file system (for example, a backslash (\) for MSDOS®/Windows®
FAT, or a colon (:) for the Macintosh®).
The following example shows filesystemindependent
code you can use to open Book1.xls, assuming that Book1.xls is
saved in the folder that contains the executable file.
The other relatively safe place to store a workbook is in the
Library folder. You can use the LibraryPath property instead
of the Path property to return a string that specifies
the Library folder. The following code shows how you would alter
the preceding example to use the LibraryPath property.
Instead of hardcoding a file name with the Open method,
you may want to give the user the option of selecting a file to
open. The GetOpenFilename method displays the standard
Open dialog box, but the method returns a string instead
of opening a file. The string contains the fully qualified path
and file name. The following example demonstrates the GetOpenFilename
method by displaying the return value in a message box and then
opening the file.
Creating and Saving Workbooks
You create a new workbook by applying the Add method to
the Workbooks collection. Remember to set the return value
of the Add method to an object variable so that you can
refer to the new workbook in your code.
When you save a new workbook for the first time, use the SaveAs
method. For subsequent saves, use the Save method. The
GetSaveAsFilename method is very similar to the GetOpenFilename
method, which is described in the preceding section. The following
example shows how to create a new workbook and then save it using
the GetSaveAsFilename method.
Closing Workbooks
To close a workbook, use the Close method of the Workbook
object. You can close a workbook without saving changes, as shown
in the following example.
This code uses the GetOpenFilename method to select the
workbook to open, makes some changes to the workbook (indicated
by the comments), and then closes the workbook without saving
the changes.
Sub OpenBook1()
Set myBook = Workbooks.Open(Filename:="BOOK1.XLS")
MsgBox myBook.Worksheets(1).Range("A1").Value
End Sub
Sub OpenBook1()
EXEPath = Application.Path & Application.PathSeparator
fName = EXEPath & "BOOK1.XLS"
Set myBook = Workbooks.Open(Filename:=fName)
MsgBox myBook.Worksheets(1).Range("A1").Value
End Sub
Sub OpenBook1()
LibPath = Application.LibraryPath & Application.PathSeparator
fName = LibPath & "BOOK1.XLS"
Set myBook = Workbooks.Open(Filename:=fName)
MsgBox myBook.Worksheets(1).Range("A1").Value
End Sub
Sub DemoGetOpenFilename()
Do
fName = Application.GetOpenFilename
Loop Until fName <> False
MsgBox "Opening " & fName
Set myBook = Workbooks.Open(Filename:=fName)
End Sub
Sub CreateAndSave()
Set newBook = Workbooks.Add
Do
fName = Application.GetSaveAsFilename
Loop Until fName <> False
newBook.SaveAs Filename:=fName
End Sub
Sub OpenChangeClose()
Do
fName = Application.GetOpenFilename
Loop Until fName <> False
Set myBook = Workbooks.Open(Filename:=fName)
' Make some changes to myBook
myBook.Close savechanges:=False
End Sub
The Range object can represent a single cell, a range of cells, an entire row or column, a selection containing multiple areas, or a 3D range. The Range object is somewhat unusual in that it can represent both a single cell and multiple cells. There's no separate collection object for the Range object; you can think of it as being either a single object or a collection, depending on the situation. There are many different properties and methods that return a Range object, as shown in the following list.
ActiveCell
BottomRightCell Cells ChangingCells CircularReference Columns CurrentArray CurrentRegion Dependents | DirectDependents
DirectPrecedents EntireColumn EntireRow Next Offset PageRange Precedents Range | RowFields
RowRange Rows Selection TableRange1 TableRange2 TopLeftCell UsedRange VisibleRange |
For more information about these properties and methods, see the individual property and method topics in Help.
Using an A1Style String Reference
or Range Name
One of the most common ways to return a Range object is
to use an A1style reference or the name of a range, as shown
in the following table.
Remember that expressions such as Range("C1:E3").Value
= 6 assume that the Range property operates
on the active sheet. If you try to run this code with a chart
sheet active, a runtime error occurs (error 1004, "Range
method of Application class failed").
Another cause of errors is the use of the Range property
in an argument to another method, without fully qualifying the
Worksheet object to which the Range property applies.
The following example, which is supposed to sort a range of cells
on Sheet1, also causes runtime error 1004.
This error is more difficult to find, because the line that contains
the Sort method is correct. The error is caused by the
second line, which contains the Key1 argument.
This code will run correctly if Sheet1 is the active sheet, but
it will fail when it's run from another worksheet or from a module.
To avoid the error, use the Worksheets property in the
argument.
Using Numeric Row and Column Indexes
You can also return a specific cell by specifying its row and
column numbers, or indexes. You specify the row index first, followed
by the column index, as shown in the following table.
Numeric row and column indexes are useful when you want to refer
to cells by using loop counters. For example, the following code
loops through cells A1:D10 on Sheet1. If any of the cells has
a value less than 0.01, the example replaces the value with 0 (zero).
The following example shows a quick and easy way to display items
in a multiplecolumn list. The code creates a new worksheet
and sets the object variable newSheet
to refer to the worksheet. The code then creates a list of all
the names in the active workbook and displays their formulas in
A1style notation.
Using the Offset Property
You often need to return a range of cells that's a certain number
of rows or columns away from another range of cells. The Offset
property applies to a Range object, takes a RowOffset
argument and a ColumnOffset argument, and returns
a new range. The following example determines the type of data
in each cell in the range A1:A10. The code writes the data types
in the column to the right of the input cells.
Using the CurrentRegion and UsedRange
Properties
These two properties are very useful when your code operates on
ranges whose size you have no control over. The current region
is a range of cells bounded by empty rows and empty columns, or
by a combination of empty rows, empty columns, and the edges of
the worksheet.
The CurrentRegion property applies to a Range object.
There can be many different current regions on a worksheet, depending
on the Range object to which you apply the CurrentRegion
property.
Suppose that Sheet1 contains a list to which you want to apply
a number format. The only thing you know about the list is that
it begins at cell A1; you don't know how many rows or columns
it contains. The following example shows how to format the list
by using the CurrentRegion property.
The used range is bounded by the farthest upperleft and
farthest lowerright nonempty cells on a worksheet. It's
a range that contains every nonempty cell on the worksheet, as
well as all the empty cells that are interspersed among them.
There can be only one used range on a worksheet; the UsedRange
property applies to a Worksheet object, not to a Range
object.
Suppose that the active worksheet contains data from a timed experiment.
The used range contains the dates in the first column, the times
in the second column, and the measurements in the third and fourth
columns. You want to write code that combines each separate date
and time into a single value, converts that value from Greenwich
Mean Time (GMT) to Pacific Standard Time (PST), and then applies
a date format to the value. The data table can contain empty rows
and columns. You can use the UsedRange property to return
the entire used range, including any embedded blank rows. The
following example shows one way to convert and format the dates
and times.
Notice that the code uses the expression ActiveSheet.UsedRange.Columns("C")
to return the third column from the used range (although this
is the third column in the used range, it can appear in any column
on the worksheet that is, the used range can be
preceded by empty columns). You can use other Range object
properties and methods in a similar way to build complex expressions
that return subranges or superranges of a Range object.
Some properties and methods commonly used in this way are Areas,
Cells, Columns, EntireColumn, EntireRow,
Range, and Rows.
Looping on a Range of Cells
There are several different ways to loop on the cells in a range.
The examples in this section show the For Each...Next statement
and the Do...Loop statement applied to looping on a range
of cells.
Using For Each...Next
The recommended way to loop on the cells in a range is to use
the For Each...Next loop, which is also the recommended
way to loop on the elements in a collection.
The following example shows how to loop through the range A1:D10
on Sheet1, setting any number whose absolute value is less than
0.01 to 0 (zero).
Suppose that you want to modify this code to loop over a range
of cells that a user selects. One way of doing this is to use
the InputBox method to prompt the user to select a range
of cells. The InputBox method returns a Range object
that represents the selection. By using the Type
argument and error handling, you can ensure that the user selects
a valid range of cells before the input box is dismissed.
If you don't want the user to select the range, you may be able
to use the CurrentRegion property or the UsedRange
property to return a Range object. For example, if you
know that the data on Sheet1 begins at cell A1 and includes no
empty rows or columns, you can use the CurrentRegion property
to return the entire range automatically.
The following two examples show two different ways to hide every
other column in the used range on Sheet1. The first example shows
a For Each...Next loop in which the Column property
of the object variable is tested.
The second example shows a For...Next loop that tests the
loop counter.
Using Do...Loop
Occasionally, the For Each...Next loop isn't the best way
to loop on a range. Suppose that you have a column of data and
you want to write a macro that sorts the data and then deletes
rows that contain duplicate data. You could try to use a For
Each...Next loop, as shown in the following example.
Unfortunately, this code doesn't work correctly because the Delete
method is modifying the range on which For Each...Next
is looping. This causes duplicates not to be deleted in some cases.
A better solution is to use a Do...Loop structure, as shown
in the following example.
The loop tests the object variable currentCell,
exiting when it encounters an empty cell at the bottom of the
column of data. You could build an equivalent loop by testing
the value in currentCell
against an empty string, as shown in the following example.
In either case, don't forget to increment the cell at the bottom
of the Do...Loop structure (Set
currentCell = nextCell, for example).
Using the Address Property to Debug Range
Object Code
You can apply the Address property to any Range
object. The Address property returns the cell address of
a range, as a string. The following example shows how to use the
Address property to debug the HideColumns procedure.
You can also set watch expressions instead
of using message boxes. For the preceding example, you could set
two watch expressions r.Address
and r.Columns(i).Address
and then examine the values of the watch expressions in the Immediate
window. For more information about debugging, see Chapter 14,
"Debugging and Error Handling."
To do this
Use the following code
Set the value of cell A1 on Sheet1
Worksheets("Sheet1").Range("A1").Value = 3
Set the formula for cell B1 on the active sheet
Range("B1").Formula = "=5-10*RAND()"
Set the value of each cell in the range C1:E3 on the active sheet
Range("C1:E3").Value = 6
Clear the contents of the range A1:E3 on the active sheet
Range("A1", "E3").ClearContents
Set the font style for the range named "myRange" (a workbook-level name) to bold
Range("myRange").Font.Bold = True
Set the value of each cell in the range named "yourRange" (a sheet-level name)
Range("Sheet1!yourRange").Value = 3
Set an object variable to refer to a range
Set objRange = Range("myRange")
Sub SortRange()
Worksheets("Sheet1").Range("A1:B10").Sort _
key1:=Range("A1"), order1:=xlDescending
End Sub
Sub SortRange()
Worksheets("Sheet1").Range("A1:B10").Sort _
key1:=Worksheets("Sheet1").Range("A1"), order1:=xlDescending
End Sub
To do this
Use the following code
Set the value of cell A1 on Sheet1
Worksheets("Sheet1").Cells(1, 1).Value = 3
Set the formula for cell B1 on the active sheet
Cells(1, 2).Formula = "=5-10*RAND()"
Set an object variable
Set objRange = Worksheets("Sheet1").Cells(1, 1)
Sub RoundToZero()
For rwIndex = 1 to 4
For colIndex = 1 to 10
If Worksheets("Sheet1").Cells(rwIndex, colIndex) < .01 Then
Worksheets("Sheet1").Cells(rwIndex, colIndex).Value = 0
End If
Next colIndex
Next rwIndex
End Sub
Sub ListNames()
Set newSheet = Worksheets.Add
i = 1
For Each nm In ActiveWorkbook.Names
newSheet.Cells(i, 1).Value = nm.Name
newSheet.Cells(i, 2).Value = "'" & nm.RefersTo
i = i + 1
Next nm
newSheet.Columns("A:B").AutoFit
End Sub
Sub ScanColumn()
For Each c In Worksheets("Sheet1").Range("A1:A10").Cells
If Application.IsText(c.Value) Then
c.Offset(0, 1).Formula = "Text"
ElseIf Application.IsNumber(c.Value) Then
c.Offset(0, 1).Formula = "Number"
ElseIf Application.IsLogical(c.Value) Then
c.Offset(0, 1).Formula = "Boolean"
ElseIf Application.IsError(c.Value) Then
c.Offset(0, 1).Formula = "Error"
ElseIf c.Value = "" Then
c.Offset(0, 1).Formula = "(blank cell)"
End If
Next c
End Sub
Sub FormatRange()
Set myRange = Worksheets("Sheet1").Range("A1").CurrentRegion
myRange.NumberFormat = "0.0"
End Sub
Sub ConvertDates()
Set myRange = ActiveSheet.UsedRange
myRange.Columns("C").Insert
Set dateCol = myRange.Columns("C")
For Each c In dateCol.Cells
If c.Offset(0, -1).Value <> "" Then
c.FormulaR1C1 = "=RC[-2]+RC[-1]-(8/24)"
End If
Next c
dateCol.NumberFormat = "mmm-dd-yyyy hh:mm"
dateCol.Copy
dateCol.PasteSpecial Paste:=xlValues
myRange.Columns("A:B").Delete
dateCol.AutoFit
End Sub
Sub RoundToZero()
For Each r In Worksheets("Sheet1").Range("A1:D10").Cells
If Abs(r.Value) < 0.01 Then
r.Value = 0
End If
Next r
End Sub
Sub RoundToZero()
Worksheets("Sheet1").Activate
On Error GoTo PressedCancel
Set r = Application.InputBox( _
prompt:="Select a range of cells", _
Type:=8)
On Error GoTo 0
For Each c In r.Cells
If Abs(c.Value) < 0.01 Then
c.Value = 0
End If
Next c
Exit Sub
PressedCancel:
Resume
End Sub
Sub RoundToZero()
Set r = Worksheets("Sheet1").Range("A1").CurrentRegion
For Each c In r.Cells
If Abs(c.Value) < 0.01 Then
c.Value = 0
End If
Next c
End Sub
Sub HideColumns()
Set r = Worksheets("Sheet1").UsedRange
For Each col In r.Columns
If col.Column Mod 2 = 0 Then
col.Hidden = True
End If
Next col
End Sub
Sub HideColumns()
Set r = Worksheets("Sheet1").UsedRange
For i = 1 To r.Columns.Count
If i Mod 2 = 0 Then
r.Columns(i).Hidden = True
End If
Next i
End Sub
Sub BuggyRemoveDuplicates() ' DON'T USE THIS CODE!
Worksheets("Sheet1").Range("A1").Sort _
key1:=Worksheets("Sheet1").Range("A1")
Set r = Worksheets("Sheet1").Range("A1").CurrentRegion.Columns("A")
For Each c In r.Cells
If c.Offset(1, 0).Value = c.Value Then
c.Offset(1, 0).EntireRow.Delete
End If
Next c
End Sub
Sub GoodRemoveDuplicates()
Worksheets("Sheet1").Range("A1").Sort _
key1:=Worksheets("Sheet1").Range("A1")
Set currentCell = Worksheets("Sheet1").Range("A1")
Do While Not IsEmpty(currentCell)
Set nextCell = currentCell.Offset(1, 0)
If nextCell.Value = currentCell.Value Then
currentCell.EntireRow.Delete
End If
Set currentCell = nextCell
Loop
End Sub
Do While currentCell.Value <> ""
' Code to run on cells with values
Loop
Sub HideColumns()
Set r = Worksheets("Sheet1").UsedRange
MsgBox r.Address ' debugging only!
For i = 1 To r.Columns.Count
If i Mod 2 = 0 Then
r.Columns(i).Hidden = True
MsgBox r.Columns(i).Address ' debugging only!
End If
Next i
End Sub
If you've used Visual Basic (Standard, Professional, or Enterprise Edition), you're familiar with eventdriven programming; most of your Visual Basic code was probably written to respond to events, such as when the user clicks a button or when a form is loaded. In Microsoft Excel, you may have used properties such as OnSheetActivate or OnEntry to cause a macro to run when a sheet is activated or changed. This is also eventdriven programming. Microsoft Excel 97 expands the available list of events and adds event procedures that receive arguments.
With Microsoft Excel 97, you can write event procedures at the worksheet, chart, workbook, or application level. For example, the Activate event occurs at the sheet level, and the SheetActivate event is available at both the workbook and application levels. The SheetActivate event for a workbook occurs when any sheet in that workbook is activated. At the application level, the SheetActivate event occurs when any sheet in any open workbook is activated.
Worksheet and workbook event procedures are created by default for any open worksheet, chart sheet, or workbook. To write event procedures for an embedded chart or for the application, you must create a new object using the WithEvents keyword in a class module. You can also use a class module to create event procedures that can be used for more than one worksheet or workbook. For more information , see "Using Class Modules with Events" later in this chapter.
Enabling or Disabling Events
Use the EnableEvents property to enable or disable events.
For example, using the Save method to save a workbook causes
the BeforeSave event to occur. You can prevent this by setting
the EnableEvents property to False before you call
the Save method, as in the following example.
Using Events on Sheets
Events on sheets are enabled by default. To view the event procedures
for a particular sheet, use either of the following techniques:
Worksheet Events
Worksheetlevel events occur when the user activates a worksheet
or changes a worksheet cell, as shown in the following table.
For more information about an event, see the corresponding Help
topic.
Examples
The following example adjusts the size of columns A through F
whenever the worksheet is recalculated.
Some events can be used to substitute an action for the default
application behavior, or to make a small change to the default
behavior. The following example traps the rightclick event
and adds a new menu item to the shortcut menu for cells B1:B10.
Chart Events
Like worksheetlevel events, chartlevel events occur
when the user activates or changes a chart, as shown in the following
table.
For more information about an event, see the corresponding Help
topic.
Events for chart sheets are available by default in the Visual
Basic Editor. To write event procedures for an embedded chart,
you must create a new object using the WithEvents keyword
in a class module. For more information, see "Using Class Modules with Events" later in this chapter.
Example
The following example changes a point's border color when the
user changes the point's value.
Workbook Events
Workbook events occur when the user changes a workbook or any
sheet in the workbook.
For more information about an event, see the corresponding Help
topic.
Example
The following example maximizes the Microsoft Excel application
window when the workbook is opened.
Application Events
Application events occur when the user creates or opens a workbook
or when the user changes any sheet in any open workbook.
For more information about an event, see the corresponding Help
topic.
Using Class Modules with Events
Unlike sheet events, embedded charts and the Application
object don't have events enabled by default. Before you can use
events with an embedded chart or with the Application object,
you must create a new class module and declare an object of type
Chart or Application with events. You use the Class
Module command (Insert menu) in the Visual Basic Editor
to create a new class module.
To enable the events of the Application object, you'd add
the following declaration to the class module.
After the new object has been declared with events, it appears
in the Object box in the class module, and you can write
event procedures for the new object. (When you select the new
object in the Object box, the valid events for that object
are listed in the Procedure box.)
Before the procedures will run, however, you must connect the
declared object in the class module to the Application
object. You can do this from any module by using the following
declaration (where "EventClass" is the name of the class
module you created to enable events).
After you've created the X
object variable (an instance of the EventClass class), you can
set the App object of the EventClass class equal to the Microsoft
Excel Application object.
After you run the InitializeApp procedure, the App object in the
EventClass class module points to the Microsoft Excel Application
object, and the event procedures in the class module will run
whenever the events occur.
Although this may seem like a lot of work, one advantage is that
you can use the same event procedure for many objects. For example,
suppose that you declare an object of type Chart with events
in a class module, as follows.
You can then use the following code to cause the event procedures
to run whenever an event occurs for either chart one or chart
two.
You can declare Worksheet or Workbook objects with
events in a class module and use the events in the new class with
several sheets, in addition to the default event procedures. You
might use this technique to write an Activate event handler that
runs only when either sheet one or sheet five is activated. Or
you can use a Chart object declared in a class module to
write an event handler for both embedded charts and chart sheets.
Application. = False
ActiveWorkbook.Save
Application. = True
Event Description
Activate Occurs when the user activates the sheet. Use this event instead of the OnSheetActivate property.
BeforeDoubleClick Occurs when the user double-clicks a worksheet cell. Use this event instead of the OnDoubleClick property.
BeforeRightClick Occurs when the user right-clicks a worksheet cell.
Calculate Occurs when the user recalculates the worksheet. Use this event instead of the OnCalculate property.
Change Occurs when the user changes a cell formula. Use this event instead of the OnEntry property.
Deactivate Occurs when the sheet is active and the user activates a different sheet. Doesn't occur when the user shifts the focus from one window to another window showing the same sheet. Use this event instead of the OnSheetDeactivate property.
SelectionChange Occurs when the user selects a worksheet cell.
Private Sub Worksheet_Calculate()
Columns("A:F").AutoFit
End Sub
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, _
Cancel As Boolean)
For Each icbc In Application.CommandBars("cell").Controls
If icbc.Tag = "brccm" Then icbc.Delete
Next icbc
If Not Application.Intersect(Target, Range("b1:b10")) Is Nothing Then
With Application.CommandBars("cell").Controls _
.Add(Type:=msoControlButton, before:=6, _
temporary:=True)
.Caption = "New Context Menu Item"
.OnAction = "MyMacro"
.Tag = "brccm"
End With
End If
End Sub
Event Description
Activate Occurs when the user activates the chart sheet (doesn't work with embedded charts). Use this event instead of the OnSheetActivate property.
BeforeDoubleClick Occurs when the user double-clicks the chart. Use this event instead of the OnDoubleClick property.
BeforeRightClick Occurs when the user right-clicks the chart.
Calculate Occurs when the user plots new or changed data on the chart.
Deactivate Occurs when the sheet is active and the user activates a different sheet. Doesn't occur when the user shifts the focus from one window to another window showing the same sheet. Use this event instead of the OnSheetDeactivate property.
DragOver Occurs when the user drags data over the chart.
DragPlot Occurs when the user drags a range of cells over the chart.
MouseDown Occurs when the user clicks a mouse button while the pointer is positioned over the chart.
MouseMove Occurs when the user moves the pointer over the chart.
MouseUp Occurs when the user releases a mouse button while the pointer is positioned over the chart.
Resize Occurs when the user changes the size of the chart.
Select Occurs when the user selects a chart element.
SeriesChange Occurs when the user changes the value of a chart data point.
Private Sub Chart_SeriesChange(ByVal SeriesIndex As Long, _
ByVal PointIndex As Long)
Set p = ActiveChart.SeriesCollection(SeriesIndex).Points(PointIndex)
p.Border.ColorIndex = 3
End Sub
Event Description
Activate Occurs when the user activates the workbook.
AddInInstall Occurs when the user installs the workbook as an addin. Use this event instead of the Auto_Add macro.
AddInUninstall Occurs when the user uninstalls the workbook as an add-in. Use this event instead of the Auto_Remove macro.
BeforeClose Occurs before the workbook closes. Use this event instead of the Auto_Close macro.
BeforePrint Occurs before the workbook is printed.
BeforeSave Occurs before the workbook is saved. Use this event instead of the OnSave property.
Deactivate Occurs when the workbook is active and the user activates a different workbook.
NewSheet Occurs after the user creates a new sheet.
Open Occurs when the user opens the workbook. Use this event instead of the Auto_Open macro.
SheetActivate Occurs when the user activates a sheet in the workbook. Use this event instead of the OnSheetActivate property.
SheetBeforeDoubleClick
Occurs when the user double-clicks a worksheet cell (not used with chart sheets). Use this event instead of the OnDoubleClick property.
SheetBeforeRightClick
Occurs when the user right-clicks a cell on a worksheet (not used with chart sheets).
SheetCalculate Occurs after the user recalculates a worksheet (not used with chart sheets). Use this event instead of the OnCalculate property.
SheetChange Occurs when the user changes a cell formula (not used with chart sheets). Use this event instead of the OnEntry property.
SheetDeactivate Occurs when the user activates a different sheet in the workbook. Use this event instead of the OnSheetDeactivate property.
SheetSelectionChange
Occurs when the user changes the selection on a worksheet (not used with chart sheets).
WindowActivate Occurs when the user shifts the focus to any window showing the workbook. Use this event instead of the OnWindow property.
WindowDeactivate Occurs when the user shifts the focus away from any window showing the workbook. Use this event instead of the OnWindow property.
WindowResize Occurs when the user opens, resizes, maximizes, or minimizes any window showing the workbook.
Sub Workbook_Open()
Application.WindowState = xlMaximized
End Sub
Event Description
NewWorkbook Occurs when the user creates a new workbook.
SheetActivate Occurs when the user activates a sheet in an open workbook. Use this event instead of the OnSheetActivate property.
SheetBeforeDoubleClick
Occurs when the user double-clicks a worksheet cell in an open workbook (not used with chart sheets). Use this event instead of the OnDoubleClick property.
SheetBeforeRightClick
Occurs when the user right-clicks a worksheet cell in an open workbook (not used with chart sheets).
SheetCalculate Occurs after the user recalculates a worksheet in an open workbook (not used with chart sheets). Use this event instead of the OnCalculate property.
SheetChange Occurs when the user changes a cell formula in an open workbook (not used with chart sheets). Use this event instead of the OnEntry property.
SheetDeactivate Occurs when the user deactivates a sheet in an open workbook. Use this event instead of the OnSheetDeactivate property.
SheetSelectionChange
Occurs when the user changes the selection on a sheet in an open workbook.
WindowActivate Occurs when the user shifts the focus to an open window. Use this event instead of the OnWindow property.
WindowDeactivate Occurs when the user shifts the focus away from an open window. Use this event instead of the OnWindow property.
WindowResize Occurs when the user resizes an open window.
WorkbookActivate Occurs when the user shifts the focus to an open workbook.
WorkbookAddInInstall
Occurs when the user installs a workbook as an add-in.
WorkbookAddInUninstall
Occurs when the user uninstalls a workbook as an add-in.
WorkbookBeforeClose
Occurs before an open workbook is closed.
WorkbookBeforePrint
Occurs before an open workbook is printed.
WorkbookBeforeSave
Occurs before an open workbook is saved.
WorkbookDeactivate
Occurs when the user shifts the focus away from an open workbook.
WorkbookNewSheet Occurs when the user adds a new sheet to an open workbook.
WorkbookOpen Occurs when the user opens a workbook.
Public WithEvents App As Application
Public X As New EventClass
Sub InitializeApp()
Set X.App = Application
End Sub
Public WithEvents cht As Chart
Dim C1 As New EventClass
Dim C2 As New EventClass
Sub InitializeCharts
Set C1.cht = Worksheets(1).ChartObjects(1).Chart
Set C2.cht = Worksheets(1).ChartObjects(2).Chart
End Sub