Accessing Cells In A Range
You do not need to use the .Cells method to access specific cells in a range.
For
example, you can use
Range("MyRange")(1,2)
rather than
Range("MyRange").Cells(1,2)
See Alan Beban's explanation of this method for more details.
Related to this is the shortcut method of refering to cells. VBA will allow you
reference cells with [A1] rather than Range("A1"). While the [A1]
syntax is easier to type, it is slower to execute than the Range("A1")
syntax.
Calculation Mode
Normally, Excel will recalculate a cell or a range of cells when that cell's or range's
precedents have changed. This may cause your workbook to recalculate too
often, which will slow down performance. You can prevent Excel from recalculating
the workbook by using the statement:
Application.Calculation = xlCalculationManual
At the end of your code, you can set the calculation mode back to automatic with the
statement:
Application.Calculation = xlCalculationAutomatic
Remember, though, that when the calculation mode is xlCalculationManual,
Excel doesn't update values in cells. If your macro relies on an updated cell value,
you must force a Calculate event, with the .Calculate method, which may be applied to either a specific
range (Range("MyRange").Calculate) or to the
entire workbook (Calculate).
Collection Indexes
An individual item of a collection object may be accessed by either its name or by its
index into the collection. For example, if you have three worksheets
("Sheet1", "Sheet2", and "Sheet3") in a workbook
("MyWorkbook"), you can reference "Sheet2" with either
Worksheets("Sheet2")
or
Worksheets(2)
In general, the index number method (Worksheets(2)) is
considerably faster than the index name method (Worksheets("Sheet2")).
However, the number and order of items in a collection may change, so it is usually
safer and easier to refer to items in a collection by their name, rather than their index
number.
Constants
Whenever you can, declare values as constants, rather than variables.
Since
their values never change, they are evaluated only once when your code is compiled, rather
than each time they are used at run time.
Early Binding
This is closely tied with Specific Object Type Declaration.
If you're
going to work with another application, such as Word, declare your OLE object directly,
rather than as an Object type variable. By doing so, a great deal of overhead is
done at compile time ("Early Binding") rather than at run time ("Late
Binding"). For example, use
Dim WordObj As Word.Application
rather than
Dim WordObj As Object
Also see Using Variables (Properly) In VBA.
FOR EACH Loops
When looping through a collection it is usually faster than the FOR EACH statement
rather than using the index. For example, the first code loop is faster than the
second:
Dim WS as Worksheet
For Each WS In Worksheets
MsgBox WS.Name
Next WS
Dim i as Integer
For i = 1 To Worksheets.Count
MsgBox Worksheets(i).Name
Next i
Range Objects Not Selection Object
Generally, it is not necessary to select a range before working with it. For
example, it is more efficient to use
Range("A1").Font.Bold = True
Rather than
Range("A1").Select
Selection.Font.Bold = True
Screen Updating
You can turn off screen updating so that Excel does not update the screen image as your
code executes. This can greatly speed up your code.
Application.ScreenUpdating = FALSE
Be sure to restore the setting to True at the end of
your macro. Older version of Excel would automatically restore the setting; Excel97
does not.
Simple Objects Rather Than Compound Objects
If you've got to make repeated references to an object, such a range, declare an object of
that type, set it to the target object, and then use your object to refer to the target.
For example,
Dim MyCell As Range
Set MyCell =
Workbooks("Book2").Worksheets("Sheet3").Range("C3")
....
MyCell.Value = 123
By referring directly to
MyCell
, VBA can access the object directly, rather than resolving
the complete path to the object each time. This method is useful only when you are
accessing an object several times during code execution.
Specific Object Type Declaration
If possible avoid using the Object or Variant data types. These data types require
considerable overhead to determine their types. Instead, use explicit data types,
such as
Dim MySheet As Worksheet rather than
Dim MySheet As Object
Or
Dim NumRows As Long rather than
Dim NumRows As Variant
This is especially true with index variables in For Next loops, since a Variant type
has to be re-evaluated each iteration of the loop.
Also see Using Variables (Properly) In VBA.
WITH Statements
If you are using several statement in a row that apply to the same object, use a WITH
statement, rather than fully qualifying the object each time. For example,
With Worksheets("Sheet1").Range("A1")
.Font.Bold = True
.Value = 123
End With
Worksheet Functions
You can use Excel's standard worksheet functions in your VBA code, rather than writing the
functions in VBA. Since these are fully executable instructions in native code,
rather than interpreted VBA code, they run much faster. For example, use
MySum =
Application.WorksheetFunction.Sum(Range("A1:A100"))
rather
than
For Each C In Range("A1:A100")
MySum = MySum + C.Value
Next C