Vous êtes sur la page 1sur 28

Excel VBA Best Practice

Simon Murphy
simon.murphy@codematic.net
Developer Codematic Ltd
UK XL User
Conference 2006

Spreadsheet background

Up to 200 Mb size
Up to 1 Million formulas
1-10,000 unique formulas
5-10,000 lines of VBA
Billions in values
Often linked to other technologies such as OLAP, ADO,
COM or .net etc.
Finance, Banking and Sales and Marketing areas
Development cost up to $1M
Active member of Eusprig European Spreadsheet Risk
group dedicated to raising awareness of dangers and
error rates in commercial spreadsheets www.eusprig.org
UK XL User
Conference 2006

Security
Fundamental Imperative
Development process
Development environment
Design considerations
High quality code

Avoiding common errors


Debugging
Testing
Documentation
Resources

General
Modules
Procedures
Blocks
Variables
Excel Specific advice
Classes

UK XL User
Conference 2006

Agenda

Security

Is everybodys concern
Spreadsheets can be used as a staging board for privilege escalation (with
your login details!)
Consider SD3 +C
Secure by

Design
Default
Deployment
Communication

Threat Modelling Assets, Threats


Threat Types STRIDE

Threats rate with DREAD

Spreadsheets (all flavours) are fairly insecure

Set macro security to high and use code signing certificates.


See Microsoft MOC 2840A Implementing security for more info.

(Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service,


Elevation of Privilege)
(Damage potential, Reproducibility, Exploitability, Affected Users,
Discoverability)
Compiled UDFs (.net, COM, XLL) and Database servers can help

UK XL User
Conference 2006

Fundamental Imperative
Manage complexity (McConnell)
Solution complexity grows at 4 x the rate of
problem complexity. (Glass)
[Things] should be as simple as they can be, but
no simpler (Einstein)
K.I.S.S.
This principle should drive all other work.
Easier to build, easier to test, easier to
document, easier to use, etc [No conflict]
UK XL User
Conference 2006

Development Process

Systems Development lifecycle

Requirements,
Analysis,
Logical Design,
<Technology Choice>,
Physical Design,
Construction,
Test,
Release,
Maintain.
In some shape or form.

Understanding the requirements is critical and difficult


Some sort of structured approach is useful
Build a library of useful code and references
UK XL User
Conference 2006

Design 2 Questions, 2 Approaches


2 Questions
What will happen when things go right?
What will happen when things go wrong?

2 Approaches:
What will the system do?
What real world objects am I modelling?

UK XL User
Conference 2006

Coupling
How strongly 2 separate elements depend on
each other
Low coupling is better, especially through clearly
defined interfaces
High coupling often means hidden dependencies
which generally leads to incorrect modifications
(side effects)
Example: hard coded cell addresses in VBA code
Example: Gobal/Public variables
UK XL User
Conference 2006

Fan in / fan out


Low fan in a VBA routine depends on
only a few other units
Good because it minimises dependencies and
reduces complexity

High fan out a VBA routine is used by


many others
Good because it minimises duplication
- Good because routine is more thoroughly
exercised
UK XL User
Conference 2006

Development Environment

Option explicit
Dont warn about syntax errors
Actual set up - which windows are visible etc
Use a code library
Use MZ tools
Other tools call tree, indenter, reference
checker, BYG
Source control, even just exporting as text

UK XL User
Conference 2006

Design Considerations

Simplicity
Testability
Cohesion and coupling
Fan in fan out
Encapsulation and separation
Reusability
What does it do, or what are you modelling?
N tier especially msgbox and error handling
Consider future changes and/or enhancements
Design patterns eg: singleton, factory, facade
Design normal case and error case

UK XL User
Conference 2006

High Quality Code General 1

Naming convention:
Option 1 fit in with current standards (eg Reddick 3 letter)
Option 2 give everything a simple, distinctive, non abbreviated descriptive
name
Procedures verb noun combination
Variables add scope prefix, data type maybe, usage more useful eg
m_rwCustomer for row in customer table or colMonth for month
column.
Only use a type prefix if you know what it is doing for you and you value that.
(eg probably dont need obj)
Avoid most comments make meaning crystal clear in the code.
Move non standard code and workarounds to named routines, and comment if
necessary
refactor early and often
build test routines as you go, and at least step through in the debugger.

UK XL User
Conference 2006

High Quality Code General 2

Recognise when you move from procedure based design to module/object


based (eg procs need to return >1 value, lots of parameters get passed all
around)
Object Oriented designs can be useful, but can cost performance
The biggest factor on performance is design
Be aware of Excel/VBA limitations, and clear on its strengths
Use TODO and maybe Enhancement comments (dont release until TODOs
cleared (use edit find in project)
Use shift+F2 for definitions, F8, Shift+F8 and Ctrl+Shift+F8 (step out) and
stop
Note compiler is weak compared to C++
Use code cleaner regularly
Differentiate style from quality
Use the most restrictive scope that works for variables and routines

UK XL User
Conference 2006

High Quality Code - Modules


As solution complexity increases think in terms of modules rather
than procedures
Use enums to add understanding
Could use types but probably better to go straight to classes.
Module name should explain what it does, a comment at the top
may be useful.
May need 1 or 2 global variables, but may need lots of module level
variables
A module should represent a bunch of closely related things eg: use
common data
Use Option private module otherwise public routines will be listed in
the user defined functions list.
Forms should usually call straight out to a class or module to do the
real work.

UK XL User
Conference 2006

High Quality Code - Procedures


Anatomy of a procedure/object initialisation, process, clear up,
error handling
Short routines 40-50 lines max (one screens worth) (easier to
understand but not proven to reduce errors)
A procedure should do one thing well
Prefer functions (Boolean success/failure)
Use parameters rather than global variables (max 7+/- 2)
Avoid application.run breaks VBA error handling
Use separate routines for separate error handling
Consider error handling early, use break on all errors when testing
Use environ rather than api where possible (simple)
All call tree parents should have error handling
Test performance dont guess (see perfmon)
Protect procedures from bad input (including malicious input)

UK XL User
Conference 2006

High Quality Code - Blocks


Code block start and end together
IF using Ifthen code an Else if, add a comment, only
remove it if you are sure there is no else case (missing
the else is a common error)
Code the expected behavoir first, usually.
Use do while and do until loops, be sure they will end, I
generally mainly use for next and for each next, finding
out the end first helps with status bar updates.
In a Select Case always have a default case, possibly
with an error warning.

UK XL User
Conference 2006

High Quality Code - Variables

Dont reuse variables for different purposes, avoid temp


Use clear data types, and control them (watch out for implicit coercion)
Variants are often easier to work with than arrays
Pass parameters byVal if they are not to be changed (watch for coercion)
Explicitly use byRef in an input parameter is to be changed, but watch for signs to
redesign
Dont implicitly use the default property, be explicit (eg range.value)
Magic numbers and strings should be made into constants.
Use explicit data casting Cstr() Cbool() etc
Code with early binding if at all possible (new), change to late binding to support multiple
versions or if component may not be installed. Late can be slower and may need better
error handling.
Can define all variables together at top or just before they are needed both have pros
and cons.
Sometimes a simple i, j, x or y is better than a long datatype prefixed descriptive name
for a loop index
Boolean variable should be named so True or False make sense eg use done rather
than status
Booleans should be positive eg if not found then rather than if not notFound then
Never mess with a loop counter within the loop.

UK XL User
Conference 2006

High Quality Code Excel 1

Its usually dangerous to hardcode a range reference in VBA.


Use range names to connect code to worksheet ranges
Choose a single cell range name as a start point
Choose a multi-cell range to allow the user to insert/delete
rows/columns
Use in cell text where possible, closely ties the mechanics to what the
user uses.
Always check cell text thoroughly before depending on it
Note data validation is easily bypassed
Give sheets code names and use them
Take the first few rows and columns for system use, hide them if
necessary
Check the selection type with typeOf if you are going to use it.
Generally avoid selecting and copying set values instead where
possible.
Be clear and explicit which workbook and worksheet code should
operate on, especially ThisWorkbook v ActiveWorkbook for add-ins.

UK XL User
Conference 2006

High Quality Code Excel 2


Pulling Range.Value or Range.Formula into a variant is much faster
than looping the cells.
Use worksheet.cells(r,c) structure rather than range(A &
someNumber)
Be consistent how you use ranges (I usually use
sheet.[rangeName].value)
Remember the power of R1C1 notation
Its often easier to set the formulaR1C1 than the formula of a range.
If distributing code with references, consider making it late bound.
Use standard environment management routines
Use Excel functionality wherever possible
Use doEvents where needed
Work upwards when deleting rows, otherwise counters get messed up
Watch for inadvertently firing events, dont hog the onCalculate event

UK XL User
Conference 2006

High Quality Code - Classes


Classes result from asking what am I modelling? rather
than what is this system to do?
Full class based design may be overkill for most VBA
applications
Hard/impossible to combine the best of spreadsheets with
proper OO data hiding is not possible.
Classes may be useful when a set of routines share lots of
data and it becomes cumbersome to pass around as
parameters
Or when you need to return a complex type from a routine

UK XL User
Conference 2006

Avoiding Common Errors


Consider lifetime initialise, set, use, destroy (CRUD
Create, read, update, delete)
Off by one errors, especially ranges into variants, arrays,
loops and ubound()
Watch for index cross talk
Dim x, y as integer => x is a variant
StrComp, InStr check the documentation

UK XL User
Conference 2006

Debugging and Testing


Debugging

Immediate window
Locals
Debug.print debug.assert

Testing

Pre-conditions and post conditions


Use a test module, and application.run for private routines
Test early and test often
Keep all test code it can act as a specification, and can give comfort that
later changes do not break anything
Get good test data realistic, test full range including boundary conditions,
but weight testing towards real world use.
Execution testing v static testing and code inspection/review.
Unit testing, system testing, user acceptance testing.

UK XL User
Conference 2006

Documentation
If you design for simplicity only very minor additional
documentation is needed
Design and build the user Interface with the Users needs
primary, the documentation will automatically be there
Design and build the business logic parts with the
maintainers needs primary, the main documentation will
automatically be there, expand as required.
Integral tests should explicitly clarify intent.
Reports should contain enough description to be
meaningful.
External documentation is almost always so out of date its
worse than useless.
Excessive documentation is too hard to plod through
Poorly targeted documentation is pointless
Working software is more useful than documentation
Sometimes documentation is important
UK XL User
Conference 2006

Documentation
Call tree print out should be enough for most uses
Be clear who the target audience is
Should be auto generated from source code if it is to be up
to date.
Stepping through code is often the easiest way to
understand it.
Download a VBA to HTML addin to pretty up code for
printing.
PUP provides a nice summary, MZ Tools creates a weighty
document.

UK XL User
Conference 2006

Extending Excel
Excel is powerful not perfect
Leverage benefits whilst managing weaknesses
by using complimentary technologies
Data: VBA, ADO, ODBC, OLAP, .net, COM, Info
Bridge, XML, DDE, Web Queries, SOX Solution
Accelerator
Logic: VBA, COM, .net, xll, Pivots, Filters
Search the web for vast array of free or cheap
tips and tools.
UK XL User
Conference 2006

Summary

Manage complexity
Consider security carefully
Excel/VBA not the best tool for everything
Be defensive, especially with inputs
Understand your data
Aim for cohesive models with low coupling
Use names to connect VBA to worksheets
Use complimentary technologies where
appropriate
Manage documentation
UK XL User
Conference 2006

Resources
Books

Code complete 2 Steve McConnell


Professional Excel Development Stephen Bullen, Rob Bovey &
John Green
VBA Developers Handbook Ken Getz

Tools

www.oaltd.co.uk (Stephen Bullen), Call Tree, Smart Indenter


www.BYGSoftware.com Toolbar creator and back up.
www.appspro.com (Rob Bovey) code cleaner
www.j-walk.com (John W), PUP
www.MZ-tools.com MZ tools VBA IDE addin.
www.codematic.net reference checker.

UK XL User
Conference 2006

Questions?
simon.murphy@codematic.net
Spreadsheet consulting, reviewing,
maintaining, rescuing, migrating, add-in
development etc.
Staff coaching, mentoring and training

Websites
www.codematic.net
www.xlanalyst.co.uk
UK XL User
Conference 2006

Vous aimerez peut-être aussi