Tải bản đầy đủ (.pdf) (570 trang)

(Business solutions) bill jelen, tracy syrstad VBA and macros for microsoft excel que pub (2004)

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (16.25 MB, 570 trang )


C o n t e n t s a t a G l a n c e
Introduction

........................................................

1

I First Steps up the VBA Learning Curve

?usinesssolutions
VBA and Macros
for


Microsoft Excel

1
2
3
4
5
6
7
8
9

Unleash the Power of Excel with VBA! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
This Sounds Like BASIC, So Why Doesn’t It Look Familiar? . . . . . . . . . 29
Referring to Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
User-Defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75


Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
R1C1 Style Formulas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Event Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
UserForms—An Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

II Automating Excel Power in VBA
10
11
12
13
14
15
16

Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Mining with Advanced Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Pivot Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Excel Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reading from and Writing to the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XML in Excel 2003 Professional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Automating Word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

III Techie Stuff You Will Need to Produce Applications
for the Administrator to Run
17 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18 Text File Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19 Using Access as a Back End to Enhance Multi-User
Access to Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20 Creating Classes, Records, and Collections . . . . . . . . . . . . . . . . . . . . . . . .

21 Advanced UserForm Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22 Windows Application Programming Interface (API) . . . . . . . . . . . . .
23 Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24 Using Custom Menus to Run Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25 Add-Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26 Case Study—Designing an Excel Application . . . . . . . . . . . . . . . . . . . .

Bill Jelen, Mr. Excel
Tracy Syrstad

800 East 96th Street
Indianapolis, Indiana 46240

175
207
235
291
331
349
359

379
387
401
415
433
453
467
481
497

505

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517


Associate Publisher

VBA and Macros for Microsoft Excel
Copyright  2004 by Sams Publishing
All rights reserved. No part of this book shall be reproduced,
stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without written permission from the publisher. No patent liability is
assumed with respect to the use of the information contained
herein. Although every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions. Nor is any liability assumed for
damages resulting from the use of the information contained
herein.
International Standard Book Number: 0-7897-3129-0
Library of Congress Catalog Card Number: 2004102247
Printed in the United States of America
First Printing: April 2004
06

05

04

03

Michael Stephens

Acquisitions Editor

Loretta Yates

Development Editor
Sean Dixon

Managing Editor
Charlotte Clapp

Project Editor
Andy Beaster

Copy Editor
Margo Catts

Indexer
Erika Millen

Proofreader
Kathy Bidwell

Technical Editor
4

3

2

1

Trademarks

All terms mentioned in this book that are known to be trademarks
or service marks have been appropriately capitalized. Sams
Publishing cannot attest to the accuracy of this information. Use
of a term in this book should not be regarded as affecting the
validity of any trademark or service mark.
Warning and Disclaimer
Every effort has been made to make this book as complete and as
accurate as possible, but no warranty or fitness is implied. The
information provided is on an “as is” basis. The authors and the
publisher shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the
information contained in this book.
Bulk Sales
Sams Publishing offers excellent discounts on this book when
ordered in quantity for bulk purchases or special sales. For more
information, please contact
U.S. Corporate and Government Sales
1-800-382-3419

For sales outside of the U.S., please contact
International Sales
1-317-428-3341


Tom Urtis

Publishing Coordinator
Cindy Teeters

Book Designer
Anne Jones


Page Layout
Bronkella Publishing
Kelly Maish
Michelle Mitchell


Contents

Contents
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Getting Results with VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
What Is in This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Getting Up the Learning Curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Excel VBA Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
The Techie Stuff Needed to Produce Applications for Others . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Will This Book Teach Excel? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4
A Brief History of Spreadsheets and Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4
The Future of VBA and Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5
Special Elements and Typographical Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7

I FIRST STEPS UP THE VBA LEARNING CURVE
1 Unleash the Power of Excel with VBA! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
The Power of Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
Barriers to Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
The Macro Recorder Doesn’t Work! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
Visual Basic Is Not Like BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
The Good News—It Is Easy to Climb the Learning Curve . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12
The Great News—Excel with VBA Is Worth the Effort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12

Knowing Your Tools—The Visual Basic Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13
Macro Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
Very High Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
High Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Medium Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Low Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Overview of Recording, Storing, and Running a Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Filling Out the Record Macro Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
Running a Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16
Creating a Macro Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16
Assigning a Macro to a Form Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17
Understanding the Visual Basic Editor (VBE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
VBE Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
The Project Explorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
The Properties Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20

iii


iv

VBA and Macros for Microsoft Excel

Examining Code in the Programming Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22
Running the Macro on Another Day Produces Undesired Results . . . . . . . . . . . . . . . . . . . . . . . . . .24
A Possible Solution: Using Relative References when Recording . . . . . . . . . . . . . . . . . . . . . . .25
Frustration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
Next Steps: Learning VBA Is the Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28

2 This Sounds Like BASIC, So Why Doesn’t It Look Familiar? . . . . . . . . . . . . . . . . .29

I Can’t Understand This Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
Understanding the Parts of VBA “Speech” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Is VBA Really This Hard? No! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
VBA Help Files—Using F1 to Find Anything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Using Help Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .35
Examining Recorded Macro Code—Using the VB Editor and Help . . . . . . . . . . . . . . . . . . . . . . . . .36
Optional Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
Defined Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .37
Properties Can Return Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .41
Using Debugging Tools to Figure Out Recorded Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
Stepping Through Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
More Debugging Options—Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .44
Backing Up or Moving Forward in Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
Not Stepping Through Each Line of Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
Querying Anything While Stepping Through Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
Using a Watch to Set a Breakpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
Using a Watch on an Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .50
The Ultimate Reference to All Objects, Methods, Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51
Five Easy Tips for Cleaning Up Recorded Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
Tip 1: Don’t Select Anything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
Tip 2: Ride the Range from the Bottom to Find Last Row . . . . . . . . . . . . . . . . . . . . . . . . . . . . .54
Tip 3: Use Variables to Avoid Hard-coding Rows and Formulas . . . . . . . . . . . . . . . . . . . . . . . . .55
Tip 4: Learn to Copy and Paste in a Single Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .55
Tip 5: Use With...End With If You Are Performing Multiple Actions to the Same
Cell or Range of Cells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .56
Putting It All Together—Fixing the Recorded Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .56
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .59


Contents


3 Referring to Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
The Range Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .61
Using the Top-Left and Bottom-Right Corners of a Selection to Specify a Range . . . . . . . . . . . . . .62
Shortcut for Referencing Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
Named Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .62
Referencing Ranges in Other Sheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .63
Referencing a Range Relative to Another Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .63
Using the Cells Property to Select a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .64
Using the Cells Property in the Range Property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
Using the Offset Property to Refer to a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
Using the Resize Property to Change the Size of a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67
Using the Columns and Rows Properties to Specify a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . .68
Using the Union Method to Join Multiple Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .68
Using the Intersect Method to Create a New Range from Overlapping Ranges . . . . . . . . . . . .69
Using the IsEmpty Function to Check Whether a Cell Is Empty . . . . . . . . . . . . . . . . . . . . . . . . . . .69
Using the CurrentRegion Property to Quickly Select a Data Range . . . . . . . . . . . . . . . . . . . . . .70
Using the Areas Collection to Return a Non-contiguous Range . . . . . . . . . . . . . . . . . . . . . . . . . . . .74
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .74

4 User-Defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .75
Creating User-Defined Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .75
Useful Custom Excel Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
Set the Current Workbook’s Name in a Cell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
Set the Current Workbook’s Name and File-Path in a Cell . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
Check Whether a Workbook Is Open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .77
Check Whether a Sheet in an Open Workbook Exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .78
Count the Number of Workbooks in a Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79
Retrieve UserID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79
Retrieve Date and Time of Last Save . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81

Retrieve Permanent Date and Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81
Validate an Email Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82
Sum Cells Based on the Interior Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .83
Retrieve Interior Cell Color Name or Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .84
Retrieve Text Color Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .87
Count Unique Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .88
Remove Duplicates from a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
Find the First Non-Zero-Length Cell in a Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91
Substitute Multiple Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .92
Retrieve Numbers from Mixed Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93

v


vi

VBA and Macros for Microsoft Excel

Convert Week Number into Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94
Separate Delimited String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .94
Sort and Concatenate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .95
Sort Numeric and Alpha Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .97
Search for a String Within Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .98
Reverse the Contents of a Cell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99
Multiple Max . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99
Return Hyperlink Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100
Return the Column Letter of a Cell Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Static Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Using Select Case on a Worksheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102


5 Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
For...Next Loops

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
Using Variables in the For Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
Variations on the For...Next Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
Exiting a Loop Early After a Condition Is Met . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
Nesting One Loop Inside Another Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
Do Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .108
Using the While or Until Clause in Do Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111
While...Wend Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
The VBA Loop: For Each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
Object Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .116

6 R1C1 Style Formulas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Referring to Cells: A1 Versus R1C1 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Why Care About R1C1 Style? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Not Just an Annoyance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Switching Excel to Display R1C1 Style References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .118
The Miracle of Excel Formulas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
Enter a Formula Once and Copy 1,000 Times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
The Secret—It Is Not That Amazing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
Explanation of R1C1 Reference Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
Using R1C1 with Relative References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
Using R1C1 with Absolute References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .122
Using R1C1 with Mixed References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Referring to Entire Columns or Rows with R1C1 Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Replacing Many A1 Formulas with a Single R1C1 Formula . . . . . . . . . . . . . . . . . . . . . . . . . . .124

Remembering Column Numbers Associated with Column Letters . . . . . . . . . . . . . . . . . . . . .125


Contents

Conditional Formatting—R1C1 Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126
Setting Up Conditional Formatting in the User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . .126
Setting Up Conditional Formats in VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127
Array Formulas Require Conditional Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130

7 Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
Global Versus Local Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
Adding Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .132
Deleting Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
Types of Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
Formulas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .135
Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
Using Arrays in Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
Reserved Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Hiding Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
Checking for the Existence of a Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140

8 Event Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
Levels of Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
Using Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .141
Event Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
Enabling Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142

Workbook Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Workbook_Activate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Workbook_Deactivate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Workbook_Open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Workbook_BeforeSave(ByVal SaveAsUI As Boolean,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Workbook_BeforeClose(Cancel As Boolean) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145
Workbook_NewSheet(ByVal Sh As Object) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .146
Workbook_WindowResize(ByVal Wn As Window) . . . . . . . . . . . . . . . . . . . . . . . . . . .146
Workbook_WindowActivate(ByVal Wn As Window) . . . . . . . . . . . . . . . . . . . . . . . .146
Workbook_WindowDeactivate(ByVal Wn As Window) . . . . . . . . . . . . . . . . . . . . . .146
Workbook_AddInInstall() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
Workbook_AddInUninstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
Workbook_SheetActivate(ByVal Sh As Object) . . . . . . . . . . . . . . . . . . . . . . . . . .147
Cancel As Boolean)

Workbook_BeforePrint(Cancel As Boolean)

Workbook_SheetBeforeDoubleClick (ByVal Sh As Object,
ByVal Target As Range, Cancel As Boolean)

. . . . . . . . . . . . . . . . . . . . . . . .147

Workbook_SheetBeforeRightClick(ByVal Sh As Object,
ByVal Target As Range, Cancel As Boolean)
Workbook_SheetCalculate (ByVal Sh As Object)

. . . . . . . . . . . . . . . . . . . . . . . .147

. . . . . . . . . . . . . . . . . . . . . . .147

vii


viii

VBA and Macros for Microsoft Excel

148
. . . . . . . . . . . . . . . . . . . . . .148

Workbook_SheetChange (ByVal Sh As Object, ByVal Target As Range)
Workbook_SheetDeactivate (ByVal Sh As Object)

Workbook_SheetFollowHyperlink (ByVal Sh As Object,
ByVal Target As Hyperlink)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .148

Workbook_SheetSelectionChange (ByVal Sh As Object,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .148
Worksheet Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .148
Worksheet_Activate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
Worksheet_Deactivate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
ByVal Target As Range)

Worksheet_BeforeDoubleClick(ByVal Target As Range,
Cancel As Boolean)


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149

Worksheet_BeforeRightClick(ByVal Target As Range,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
Worksheet_Change(ByVal Target As Range) . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
Worksheet_SelectionChange(ByVal Target As Range) . . . . . . . . . . . . . . . . . .152
Worksheet_FollowHyperlink(ByVal Target As Hyperlink) . . . . . . . . . . . . . .152
Chart Sheet Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .152
Embedded Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .153
Chart_Activate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .153
Cancel As Boolean)

Worksheet_Calculate()

Chart_BeforeDoubleClick(ByVal ElementID As Long,

. . . . .154
. . . . . . . . . . . . . . . . . . . . . . . . . .154
Chart_Calculate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
Chart_Deactivate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
Chart_DragOver() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
Chart_DragPlot() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
ByVal Arg1 As Long, ByVal Arg2 As Long, Cancel As Boolean)

Chart_BeforeRightClick(Cancel As Boolean)

Chart_MouseDown(ByVal Button As Long, ByVal Shift As Long,

ByVal x As Long, ByVal y As Long)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154

Chart_MouseMove(ByVal Button As Long, ByVal Shift As Long,
ByVal x As Long, ByVal y As Long)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155

Chart_MouseUp(ByVal Button As Long, ByVal Shift As Long,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155

ByVal x As Long, ByVal y As Long)
Chart_Resize()

Chart_Select(ByVal ElementID As Long, ByVal Arg1 As Long,
ByVal Arg2 As Long)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155

Chart_SeriesChange(ByVal SeriesIndex As Long,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
Application-Level Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
AppEvent_NewWorkbook(ByVal Wb As Workbook) . . . . . . . . . . . . . . . . . . . . . . . . .157
AppEvent_SheetActivate(ByVal Sh As Object) . . . . . . . . . . . . . . . . . . . . . . . . .157
ByVal PointIndex As Long)


AppEvent_SheetBeforeDoubleClick(ByVal Sh As Object,
ByVal Target As Range, Cancel As Boolean)

. . . . . . . . . . . . . . . . . . . . . . . .158

AppEvent_SheetBeforeRightClick(ByVal Sh As Object,

. . . . . . . . . . . . . . . . . . . . . . . .158
. . . . . . . . . . . . . . . . . . . . . . . .158
AppEvent_SheetChange(ByVal Sh As Object, ByVal Target As Range) .158
AppEvent_SheetDeactivate(ByVal Sh As Object) . . . . . . . . . . . . . . . . . . . . . . . .158
ByVal Target As Range, Cancel As Boolean)

AppEvent_SheetCalculate(ByVal Sh As Object)


Contents

AppEvent_SheetFollowHyperlink(ByVal Sh As Object,
ByVal Target As Hyperlink)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158

AppEvent_SheetSelectionChange(ByVal Sh As Object,
ByVal Target As Range)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158

AppEvent_WindowActivate(ByVal Wb As Workbook,
ByVal Wn As Window)


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158

AppEvent_WindowDeactivate(ByVal Wb As Workbook,

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
.159
AppEvent_WorkbookActivate(ByVal Wb As Workbook) . . . . . . . . . . . . . . . . . . .159
AppEvent_WorkbookAddinInstall(ByVal Wb As Workbook) . . . . . . . . . . . . . . .159
AppEvent_WorkbookAddinUninstall(ByVal Wb As Workbook) . . . . . . . . . . . .159
ByVal Wn As Window)

AppEvent_WindowResize(ByVal Wb As Workbook, ByVal Wn As Window)

AppEvent_WorkbookBeforeClose(ByVal Wb As Workbook,
Cancel As Boolean)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159

AppEvent_WorkbookBeforePrint(ByVal Wb As Workbook,
Cancel As Boolean)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160

AppEvent_WorkbookBeforeSave(ByVal Wb As Workbook,
ByVal SaveAsUI As Boolean, Cancel As Boolean)

. . . . . . . . . . . . . . . . . . . .160

AppEvent_WorkbookNewSheet(ByVal Wb As Workbook,


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
. . . . . . . . . . . . . . . . . . . . . . . . .160
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
ByVal Sh As Object)

AppEvent_WorkbookOpen(ByVal Wb As Workbook)

9 UserForms—An Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
User Interaction Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
InputBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
MsgBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
Creating a Userform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162
Calling and Hiding a Userform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .163
Programming the UserForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
Using Basic Form Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165
Deciding Whether to Use ListBoxes or ComboBoxes in Your Forms . . . . . . . . . . . . . . . . . . . . .166
Adding Option Buttons to a UserForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .167
Adding Graphics to a UserForm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .168
Using Spinbutton on a Userform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .169
Using the Multipage Control to Combine Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .170
Verifying Field Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .170
Illegal Window Closing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172

II AUTOMATING EXCEL POWER IN VBA
10 Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
Embedded Charts Versus ChartSheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176
Embedded Charts in a ChartObject Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .176

Charts on a Chart Sheet Have No Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .178

ix


x

VBA and Macros for Microsoft Excel

Creating a Chart with VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .178
Moving from Embedded to Chart Sheet and Vice-Versa . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181
The Default Chart Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181
Using Object Variables to Streamline Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
The Anatomy of a Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .183
The Chart Area—VBA Name: ChartArea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .183
The Plot Area—VBA Name: PlotArea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .186
The Data Series—VBA Name: Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
The Chart Axes—VBA Name: Axis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .189
Grid Lines—VBA Name: HasMajorGridlines and HasMinorGridlines . . . . . . . . . . .191
Data Labels—VBA Name: DataLabels and DataLabel . . . . . . . . . . . . . . . . . . . . . . . . . .191
Chart Title, Legend, and Data Table—VBA Name: ChartTitle, HasLegend, and
HasDataTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .192
Trendlines and Error Bars—VBA Name: Trendlines and ErrorBar . . . . . . . . . . . . . . . .193
Table of Chart Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .195
Details of Various Chart Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
Settings for 3D Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
Settings for Pie Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199
Interactive Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
Using Events with Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
Exporting Charts as Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202

Drawing with X-Y Charts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203
Custom Charts with VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204
Pie Bubble Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204
Speedometer Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204
Supply Curve Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205
Hierarchical Donut Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .206

11 Data Mining with Advanced Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207
Advanced Filter Is Easier in VBA Than in Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207
Using Advanced Filter to Extract a Unique List of Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .208
Extracting a Unique List of Values with the User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . .208
Extracting a Unique List of Values with VBA Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
Getting Unique Combinations of Two or More Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .214
Using Advanced Filter with Criteria Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .215
Joining Multiple Criteria with a Logical OR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .217
Joining Two Criteria with a Logical AND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .217
Other Slightly Complex Criteria Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .218


Contents

The Most Complex Criteria—Replacing the List of Values with a Condition Created as
the Result of a Formula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .218
Being Prepared for No Records After the Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .224
Using “Filter in Place” in Advanced Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
Catching No Records When Using Filter In Place . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .225
Showing All Records After Filter In Place . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .226
Using Filter In Place with Unique Records Only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .226
The Real Workhorse: xlFilterCopy with All Records Instead of Unique Records Only . . . . . .226

Copying All Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .227
Copying a Subset of Columns and Reordering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .228
AutoFilters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .234

12 Pivot Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235
Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235
Creating a Vanilla Pivot Table in Excel Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .236
Building a Pivot Table in Excel VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .238
Getting a Sum Instead of Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240
Cannot Move or Change Part of a Pivot Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241
Figuring the Size of a Finished Pivot Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .241
Revenue by Customer for a Product Line Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243
Eliminating Blank Cells in the Data Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245
Using AutoSort to Control the Sort Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .246
Controlling the Sort Order Manually . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .247
Changing the Default Number Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .247
Suppressing Subtotals for Multiple Row Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .249
Suppressing Grand Total for Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .250
Handling Additional Annoyances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .250
Creating a New Workbook to Hold the Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .250
Moving the Summary to a Blank Report Worksheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .251
Filling in the Outline View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .252
Final Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
Adding Subtotals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .254
Putting It All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .255
Product Profitability—Issues with Two or More Data Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . .258
Defining Calculated Data Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .260
Avoid Calculated Items . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .263
Summarizing Date Fields with Grouping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .264

Grouping by Week . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267
Measuring Order Lead Time by Grouping Two Date Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . .269

xi


xii

VBA and Macros for Microsoft Excel

Advanced Pivot Table Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .271
Using the Top 10 AutoShow Feature to Produce Executive Overviews . . . . . . . . . . . . . . . . . .271
Using Pivot Table ShowDetail to Filter a Recordset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .274
Using a Page Field to Create Reports for Each Region or Product . . . . . . . . . . . . . . . . . . . . . .276
Manually Filtering to Two or More Items in a PivotField . . . . . . . . . . . . . . . . . . . . . . . . . .280
Sum, Average, Count, Min, Max, and More . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .284
Reporting Percentages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .286
Percentage of Total . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .286
Percentage Growth from Previous Month . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .286
Percentage of a Specific Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .287
Running Total . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .287
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .289

13 Excel Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291
Using VBA to Extend Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291
Conditional Formatting with More Than Three Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . .291
AutoFilter with More Than Two Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .292
File Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .293
List Files in a Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .293
Delete a Workbook After a Specific Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .295

Close and Delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .295
Import CSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .297
Read Entire CSV to Memory and Parse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .298
Combining and Separating Workbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299
Separate Worksheets into Workbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .299
Combine Workbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .300
Filter and Copy Data to Separate Worksheets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .301
Export Data to Word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .302
Working with Cell Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
List Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
Resize Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .304
Resize Comments with Centering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .305
Place a Chart in a Comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .306
Utilities to Wow Your Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .308
Using Conditional Formatting to Highlight Selected Cell . . . . . . . . . . . . . . . . . . . . . . . . . . . .308
Highlight Selected Cell Without Using Conditional Formatting . . . . . . . . . . . . . . . . . . . . . . .309
Custom Transpose Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .310
Select/Deselect Non-contiguous Cells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .311
Techniques for VBA Pros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .313
Speedy Page Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .313
Calculating Time to Execute Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315
Disable Cut, Copy, and Paste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .316
Custom Sort Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .318


Contents

Cell Progress Indicator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .319
Protected Password Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .320
Change Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .322

Custom Delete Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .323
Selecting with SpecialCells . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324
Delete Rows with Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .325
Hide the Formula Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .326
Cool Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .327
Historical Stock/Fund Quotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .327
Disable Cut, Copy, and Paste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .328
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330

14 Reading from and Writing to the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
Getting Data from the Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
Manually Creating a Web Query and Refreshing with VBA . . . . . . . . . . . . . . . . . . . . . . . . . . .332
Using VBA to Update an Existing Web Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333
Building a New Web Query with VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .334
Using Streaming Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .336
Using Application.OnTime to Periodically Analyze Data . . . . . . . . . . . . . . . . . . . . . . . . . . . .337
Scheduled Procedures Require Ready Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .337
Specifying a Window of Time for an Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .338
Cancelling a Previously Scheduled Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .338
Closing Excel Cancels All Pending Scheduled Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .339
Scheduling a Macro to Run x Minutes in the Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .339
Scheduling a Macro to Run Every Two Minutes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .339
Publishing Data to a Web Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .341
Using VBA to Create Custom Web Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343
Using Excel as a Content Management System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344
Bonus—FTP from Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .347
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .347

15 XML in Excel 2003 Professional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .349
What Is XML? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .349

Simple XML Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .350
Universal File Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .350
XML as the New Universal File Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .351
The Alphabet Soup of XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .352
Using XML to Round-Trip a Workbook from Excel to HTML and Back . . . . . . . . . . . . . . . . . . . . . .353
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358

xiii


xiv

VBA and Macros for Microsoft Excel

16 Automating Word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
Early Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .359
Compile Error: Can’t Find Object or Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .361
Late Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
Creating and Referencing Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
Keyword New . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
CreateObject Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
GetObject Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .363
Word’s Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .364
Document Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .365
Selection Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .367
Range Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .368
Bookmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .371
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .376

III TECHIE STUFF YOU WILL NEED TO PRODUCE APPLICATIONS FOR THE


ADMINISTRATOR TO RUN
17 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .379
Declare an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .379
Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .380
Fill an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .380
Empty an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .382
Arrays Can Make It Easier to Manipulate Data, But Is That All? . . . . . . . . . . . . . . . . . . . . . . . . . . .383
Dynamic Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .385
Passing an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .386
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .386

18 Text File Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .387
Importing from Text Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .387
Importing Text Files with Less Than 65,536 Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .387
Reading Text Files with More Than 65,536 Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .394
Writing Text Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .398
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .399

19 Using Access as a Back End to Enhance Multi-User Access to Data . . . . . . . . .401
ADO Versus DAO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .402
The Tools of ADO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .404
Adding a Record to the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .404
Retrieving Records from the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .406
Updating an Existing Record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .408


Contents

Deleting Records via ADO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .410

Summarizing Records via ADO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .410
Other Utilities via ADO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .411
Checking for Existence of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .411
Checking for Existence of a Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .412
Adding a Table on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .413
Adding a Field on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .413
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .414

20 Creating Classes, Records, and Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . .415
Inserting a Class Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .415
Trapping Application and Embedded Chart Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .416
Application Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .416
Embedded Chart Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .418
Creating a Custom Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .420
Using a Custom Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .421
Using Property Let and Property Get to Control How Users Utilize Custom Objects . . . .422
Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .424
Creating a Collection in a Standard Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .424
Creating a Collection in a Class Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .425
User-Defined Types (UDTs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .429
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .432

21 Advanced UserForm Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .433
Using the UserForm Toolbar in the Design of Controls on UserForms . . . . . . . . . . . . . . . . . . . . . .433
Controls and Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .434
More UserForm Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .436
Toggle Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .436
Tabstrip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .436
RefEdit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .438
Modeless Userforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .438

Hyperlinks in Userforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .439
Adding Controls at Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .440
Resizing the Userform on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .441
Adding a Control on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .442
Sizing on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .442
No AutoComplete Funtionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .442
Adding Other Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .442
Adding an Image on the Fly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .443
Putting It All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .444

xv


xvi

VBA and Macros for Microsoft Excel

Using a Scrollbar as a Slider to Select Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .446
Adding Help Tips to Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .447
Accelerator Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .447
Control Tip Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
Tab Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
Coloring the Active Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
Transparent Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .451
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .452

22 Windows Application Programming Interface (API) . . . . . . . . . . . . . . . . . . . .453
What Is the Windows API? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .453
Understanding an API Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .453
Using an API Declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .454

API Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .455
GetComputerName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .455
FileIsOpen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .456
Retrieve Display Resolution Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .457
Disable the Excel X for Closing the Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .458
Disable the X for Closing a Userform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .459
Running Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .460
Clickable Links on Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .461
Playing Sounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .462
Retrieving a File Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .462
Finding More API Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .466
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .466

23 Handling Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .467
What Happens When an Error Occurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .467
Debug Error Inside Userform Code Is Misleading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .468
Basic Error Handling with the On Error GoTo Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .470
Multiple Error Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .472
Generic Error Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .472
Handling Errors by Choosing to Ignore Them . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .472
Suppressing Excel Warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .473
Encountering Errors on Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .474
Train Your Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .474
Errors While Developing Versus Errors Months Later . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .475
Runtime Error 9: Subscript out of Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .475
RunTime Error 1004: Method ‘Range’ of Object ‘_Global’ Failed . . . . . . . . . . . . . . . . . . . . . . .476
The Ills of Protecting Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .477


Contents


More Problems with Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .478
Errors Caused by Different Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .478
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .479

24 Using Custom Menus to Run Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .481
Creating a Custom Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .481
Deleting and Creating the Custom Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .482
Adding a Single Menu Item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .483
Breaking Items into Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .484
Adding a Fly-out Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .485
Creating a Custom Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .487
Deleting and Creating the Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .487
Adding Buttons to the Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .488
Using FaceID Codes to Add Icons to the Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .489
Adding Drop-downs to the Toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .489
Remembering a Toolbar’s Position . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .490
Other Ways to Run a Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .491
Keyboard Shortcut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .491
Attach a Menu to a Command Button . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .492
Attach a Macro to an ActiveX Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .494
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .496

25 Add-Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .497
Characteristics of Standard Add-Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .497
Converting an Excel Workbook to an Add-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .498
Using Save As to Convert a File to an Add-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .499
Using the VB Editor to Convert a File to an Add-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .499
Having Your Client Install the Add-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .500
Standard Add-Ins Are Not Secure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .502

Closing Add-Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .502
Removing Add-Ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .502
Using a Hidden Workbook as an Alternative to an Add-In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .503
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .504

26 Case Study: Designing an Excel Application . . . . . . . . . . . . . . . . . . . . . . . . . . .505
About Tushar Mehta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .505
Using Excel for More Than Number Crunching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .506
The Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .506
Implementing the Solution in Excel and VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .507
Pass 1—Top-Down Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .508
Pass 1—Key Components Defined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .509
Pass 2—Top-Down Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .510

xvii


xviii

VBA and Macros for Microsoft Excel

Pass 2—Key Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .511
Pass 3—Top-Down Code Completed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .513
Pass 3—Key Components Completed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .515
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .516
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .516

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .517



About the Authors

About the Authors
Bill Jelen, “Mr. Excel,” is an accomplished Excel author and the principal behind the leading Excel Web site, MrExcel.com. As an Excel consultant, he has written Excel VBA solutions for hundreds of clients around the English-speaking world. His Web site hosts more
than 10 million page views annually. Prior to founding MrExcel.com, Jelen spent 12 years
in the trenches—working as a financial analyst for finance, marketing, accounting, and
operations departments of a $500 million public company. He lives near Akron, Ohio, with
his wife Mary Ellen and sons Josh and Zeke.

Tracy Syrstad works as a programmer and consultant for the MrExcel Consulting team.
She remembers the painful trek up the VBA learning curve while developing applications
for co-workers at a former job. She is co-editor of Holy Macro! It’s 1,900 Excel VBA Examples
CD and editor of Dreamboat On Word. She lives on an arboreous acreage in eastern South
Dakota with her husband John and dog General.

Dedications
Dedicated to Mary Ellen Jelen
—Bill

Dedicated to John Syrstad, whose confidence in me gave me strength to take this path
—Tracy

xix


xx

VBA and Macros for Microsoft Excel

Acknowledgments

Thank you to Mala Singh of XLSoft Consulting for expertise with Chapter 10. Tom Urtis
for technical editing. Jerry Kohl for many of the ideas in this book. Jeanette Garcia, Barb
Jelen, and Doug and Stacy Jefferies for technical assistance. Zeke, Josh, and Mary Ellen
Jelen for their patience. Tom Macioszek for peer review. Chad Rothschiller at Microsoft for
teaching me everything there is to know about Excel XML. Dave Gainer, Steve Zaske, Eric
Patterson, and Joe Chirilov at Microsoft. Loretta Yates, Sean Dixon, Margo Catts, Andy
Beaster, Greg Wiegand, Amy Sorokas, Kim Spilker, Erika Millen, Kathy Bidwell, Cindy
Teeters, Michelle Mitchell, and Gary Adair at Pearson. Ivana Taylor for her marketing brilliance. All the MrExcel.com readers and MVPs and clients. Dan Bricklin, Bob Frankston,
and Mitch Kapor for being spreadsheet pioneers. William Brown at Waterside. Pam Gensel
for macro lesson number 1. Robert F. Jelen for being my first programming fan. Robert K.
Jelen for inspiration. Bonnie Hilliard for P.R. Laurelle Riippa at PW. Leo LaPorte and
Fawn Luu at TechTV. Dan Poynter. Craig Crossman at Computer America. Walter
Mossberg at the Wall Street Journal.
—Bill

Thank you to Cort Chilldon-Hoff for offering support and being a sounding board when I
was stumped. Juan Pablo González Ruiz for offering his expertise, especially with the functions found in Chapter 4. Daniel Klann, Dennis Wallentin, Ivan F. Moala, Juan Pablo
González, Masaru Kaji, Nathan P. Oliver, Richie Sills, Russell Hauf, Suat Mehmet Ozgur,
Tom Urtis, Tommy Miles, Wei Jiang for their contributions to Chapter 13. Chris Lemair
for introducing me to Excel and the power of its macros. Anne Troy who introduced Bill
and I in the first place. The Computer America chat room for distracting me when I was
supposed to be working on the book.
—Tracy


We Want to Hear from You!

We Want to Hear from You!
As the reader of this book, you are our most important critic and commentator. We value
your opinion and want to know what we’re doing right, what we could do better, what areas

you’d like to see us publish in, and any other words of wisdom you’re willing to pass our
way.
As an associate publisher for Sams, I welcome your comments. You can email or write me
directly to let me know what you did or didn’t like about this book—as well as what we can
do to make our books better.
Please note that I cannot help you with technical problems related to the topic of this book. We do
have a User Services group, however, where I will forward specific technical questions related to the
book.
When you write, please be sure to include this book’s title and author as well as your name,
email address, and phone number. I will carefully review your comments and share them
with the authors and editors who worked on the book.
Email:



Mail:

Michael Stephens
Associate Publisher
Sams Publishing
800 East 96th Street
Indianapolis, IN 46240 USA

For more information about this book or another Sams title, visit our Web site at
www.samspublishing.com. Type the ISBN (0789731290) or the title of a book in the Search
field to find the page you’re looking for.

xxi




Introduction
Getting Results with VBA
As the macro language for Microsoft Excel, Visual
Basic for Applications enables you to achieve
tremendous efficiencies in your day-to-day use of
Excel.
As corporate IT departments have found themselves with long backlogs of requests, Excel users
have found that they can produce the reports
needed to run their business themselves. This is
both a good and bad thing. On the good side, without waiting for resources from IT, you’ve probably
been able to figure out how to import data and produce reports in Excel. On the bad side, you are now
stuck importing data and producing reports in
Excel.

INTRODUCTION
IN THIS INTRODUCTION
Getting Results with VBA . . . . . . . . . . . . . . . . .1
What Is in This Book . . . . . . . . . . . . . . . . . . . . . .3
A Brief History of Spreadsheets and Macros . .4
The Future of VBA and Excel . . . . . . . . . . . . . . .5
Special Elements and Typographical
Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . .6
Next Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7


2

Introduction


C A S E S T U DY
Case Study: Monthly Accounting Reports
This is a true story.Valerie is a business analyst in the accounting department of a medium-size corporation. Her company
recently installed an over-budget $16 million ERP system. As the project ground to a close, there were no resources left in
the IT budget to produce the monthly report that this corporation used to summarize each department.
Valerie, however, had been close enough to the implementation process to think of a way to produce the report herself.
She understood that she could export General Ledger data from the ERP system to a text file with comma-separated values. Using Excel,Valerie was able to import the G/L data from the ERP system into Excel.
Creating the report was not easy. Like many companies, there were exceptions in the data.Valerie knew that certain
accounts in one particular cost center needed to be reclassed as an expense. She knew that other accounts needed to be
excluded from the report entirely.Working carefully in Excel,Valerie made these adjustments. She created one pivot table
to produce the first summary section of the report. She cut the pivot table results and pasted them into a blank worksheet.Then she created a new pivot table report for the second section of the summary. After about three hours, she had
imported the data, produced five pivot tables, arranged them in a summary, and had neatly formatted the report in color.

Becoming the Hero
Valerie handed this report to her manager.The manager had just heard from the IT department that it would be months
before they could get around to producing “that convoluted report.”Valerie walked in, handed the Excel report over, and
became the instant hero of the day. In three hours,Valerie had managed to do the impossible.Valerie was on cloud nine
after a well-deserved “atta-girl.”

More Cheers
The next day, this manager attended the monthly department meeting.When the department managers started complaining that they couldn’t get the report from the ERP system, this manager pulled out his department report and placed
it on the table.The other managers were amazed. How was he able to produce this report? Everyone was greatly relieved
to hear that someone had cracked the code.The company president asked Valerie’s manager if he could have the report
produced for each department.

The Cheers Turn to Dread
You can certainly see this coming.This particular company had 46 departments.That means 46 one-page summaries had
to be produced once a month. Each required importing data from the ERP system, backing out certain accounts, producing
five pivot tables, and then formatting in color. It had taken Valerie three hours to produce the first report. She found that
after she got into the swing of things, she was able to produce the 46 reports in 40 hours.This is horrible.Valerie had a job

to do before she won the responsibility of spending 40 hours a month producing these reports in Excel.

VBA to the Rescue
Valerie found my company, MrExcel Consulting, and explained her situation. In the course of about a week, I was able to
produce a series of macros in Visual Basic that did all the mundane tasks. It imported the data. It backed out certain
accounts. It did five pivot tables and applied the color formatting. From start to finish, the entire 40-hour manual process
was reduced to two button clicks and about four minutes.


×