PTS Blog

Main menu:

PTS Utilities

Commercial Utilities developed by Peltier Technical Services

  Waterfall Chart

Excel Books

Books that I own and use while developing in Excel

Goods and Services

Excel or charting related products and services which I use or feel are worthwhile additions

Subscribe

Site search


Recent Posts

Recently Commented

March 2008
S M T W T F S
« Feb   Apr »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Archive


 

Categories


 

How To: Fix a Recorded Macro

by Jon Peltier
Peltier Technical Services, Inc., Copyright © 2008. All rights reserved.

In a recent post, I showed how to record a macro to save yourself time and effort with that repetitive task. The recorder has captured all of your keystrokes, intentional and otherwise. Objects are selected first, then acted upon. Defaults are applied indiscriminately every time the recorder followed you into a dialog. Actions you take and undo are all recorded. The result is syntactically accurate, but inefficient.

Let's clean up the code to make it run faster and smoother, without the flashing shown on screen. Go to the VB Editor and open the code module containing your recorded macro. The code recorded in the previous example is shown below.

Visual Basic:
  1. Sub RecordedMacro()
  2. '
  3. ' RecordedMacro Macro
  4. ' Macro recorded 3/7/2008 by Jon Peltier
  5. '
  6.  
  7. '
  8.     With Selection
  9.         .HorizontalAlignment = xlCenter
  10.         .VerticalAlignment = xlBottom
  11.         .WrapText = False
  12.         .Orientation = 0
  13.         .AddIndent = False
  14.         .IndentLevel = 0
  15.         .ShrinkToFit = False
  16.         .ReadingOrder = xlContext
  17.         .MergeCells = False
  18.     End With
  19.     With Selection.Font
  20.         .Name = "Arial"
  21.         .Size = 10
  22.         .Strikethrough = False
  23.         .Superscript = False
  24.         .Subscript = False
  25.         .OutlineFont = False
  26.         .Shadow = False
  27.         .Underline = xlUnderlineStyleNone
  28.         .ColorIndex = xlAutomatic
  29.     End With
  30.     With Selection.Font
  31.         .Name = "Arial"
  32.         .Size = 12
  33.         .Strikethrough = False
  34.         .Superscript = False
  35.         .Subscript = False
  36.         .OutlineFont = False
  37.         .Shadow = False
  38.         .Underline = xlUnderlineStyleNone
  39.         .ColorIndex = xlAutomatic
  40.     End With
  41.     Selection.Font.ColorIndex = 3
  42. End Sub

That's a lot of code for the small number of actions that were done while recording. We centered the text in the selected cells, changed the font to Arial, changed the font size to 12 points, and changed the text to red. Every time an action was taken, properties which were not changed during that action were still recorded, despite being unchanged. For example, the font's ColorIndex was twice "changed" to xlAutomatic, before finally being changed to 3 (red in the default Excel color palette). Removing the redundant and default statements greatly reduces the code.

Visual Basic:
  1. Sub RecordedAndFixedMacro()
  2. ' Macro recorded & fixed up 3/7/2008 by Jon Peltier
  3. '
  4.     With Selection
  5.         .HorizontalAlignment = xlCenter
  6.     End With
  7.     With Selection
  8.         With .Font
  9.             .Name = "Arial"
  10.             .Size = 12
  11.             .ColorIndex = 3
  12.         End With
  13.     End With
  14. End Sub

This macro didn't have the usual repeated cycle of select an object, format the selection, select another object, so I've included another sample below.

Visual Basic:
  1. Sub SelectAndFormatRecording()
  2. '
  3.     Range("C9:G9").Select
  4.     Selection.Font.Bold = True
  5.     Range("C11:G11").Select
  6.     Selection.Font.ColorIndex = 5
  7. End Sub

By avoiding the sequence of selections, the code is smaller and runs faster, and the screen doesn't change or even flash with each subsequent selection change.

Visual Basic:
  1. Sub FormatByReference()
  2. '
  3.     Range("C9:G9").Font.Bold = True
  4.     Range("C11:G11").Font.ColorIndex = 5
  5. End Sub

A technique for streamlining code is to group operations performed on each object within With/End With blocs. The first recorded macro above was recorded with several With/End With blocks. But frequently when recording macros, we are carrying out operations as we think of them, and operations on the same object may be scattered around the macro. In this case, we can construct our own blocks, first rearranging the code, then forming the blocks.

Visual Basic:
  1. Sub DisorderlyRecording()
  2. '
  3.     Range("J12:M19").Font.Bold = True
  4.     Range("J14:M14").Font.ColorIndex = 5
  5.     Range("J12:M19").Font.Name = "Courier New"
  6.     Range("J14:M14").Font.Italic = True
  7.     Range("J12:M19").HorizontalAlignment = xlCenter
  8. End Sub

Reordering...

Visual Basic:
  1. Sub ReorderedRecording()
  2. '
  3.     Range("J12:M19").HorizontalAlignment = xlCenter
  4.     Range("J12:M19").Font.Bold = True
  5.     Range("J12:M19").Font.Name = "Courier New"
  6.     Range("J14:M14").Font.ColorIndex = 5
  7.     Range("J14:M14").Font.Italic = True
  8. End Sub

Blocking...

Visual Basic:
  1. Sub ReorderedAndBlocked()
  2. '
  3.     With Range("J12:M19")
  4.         .HorizontalAlignment = xlCenter
  5.         With .Font
  6.             .Bold = True
  7.             .Name = "Courier New"
  8.         End With
  9.     End With
  10.     With Range("J14:M14").Font
  11.         .ColorIndex = 5
  12.         .Italic = True
  13.     End With
  14. End Sub

Note that you can nest one With/End With block within another.

For a more detailed look at optimizing recorded macros and using Excel's object model more effectively, see my colleague Tushar Mehta's Beyond the macro recorder.

In a series of upcoming posts, I'll cover the following VB topics:

Share/Save/Bookmark

Write a comment





Create Excel dashboards quickly with Plug-N-Play reports.