Static code analysis can find hundreds of opportunities in VBA code.
Rubberduck builds its own internal representation of the code, and then proceeds to analyze it. Each individual inspection can easily be disabled, or configured to issue inspection results at different severity levels ranging from
Use the Inspection Results toolwindow to review Rubberduck’s findings, search, filter, regroup results by inspection, location, type, or severity. Each inspection result comes with a detailed description of what’s being flagged and why, so you can make an enlightened decision.
Unless configured otherwise, Rubberduck automatically runs inspections after the a parser/resolver cycle completes (regardless of whether the inspection results toolwindow is displayed or not).
For the best experience, it would be recommended to first try Rubberduck with an empty project, add a new module, and write, say, a loop that counts 1 to 10 and outputs to the debug pane - then to parse that and review the inspection results; carefully review the inspection settings, and consider disabling the inspections that irreconcilably clash with your preferences: use meaningful names alone can easily produce hundreds upon hundreds of results if you’re not that much into using vowels, or if you, say, prefix all your variable names; these inspections can be re-enabled anytime you’re ready!
These inspections highlight problems that are potentially more subjective, such as short, disemvoweled identifier names.
Identifies conditional assignments to mutually exclusive Boolean literal values in conditional branches.
The assignment could be made directly to the result of the conditional Boolean expression instead.
Identifies empty 'Else' blocks that can be safely removed.
Empty code blocks are redundant, dead code that should be removed. They can also be misleading about their intent: an empty block may be signalling an unfinished thought or an oversight.
Flags publicly exposed instance fields.
Instance fields are the implementation details of a object's internal state; exposing them directly breaks encapsulation. Often, an object only needs to expose a 'Get' procedure to expose an internal instance field.
Flags identifiers that use [Systems] Hungarian Notation prefixes.
Systems Hungarian (encoding data types in variable names) stemmed from a misunderstanding of what its inventor meant when they described that prefixes identified the "kind" of variable in a naming scheme dubbed Apps Hungarian. Modern naming conventions in all programming languages heavily discourage the use of Systems Hungarian prefixes.
Locates module-level fields that can be moved to a smaller scope.
Module-level variables that are only used in a single procedure can often be declared in that procedure's scope. Declaring variables closer to where they are used generally makes the code easier to follow.
Flags parameters declared across multiple physical lines of code.
When splitting a long list of parameters across multiple lines, care should be taken to avoid splitting a parameter declaration in two.
Flags usages of members marked as obsolete with an @Obsolete("justification") Rubberduck annotation.
Marking members as obsolete can help refactoring a legacy code base. This inspection is a tool that makes it easy to locate obsolete member calls.
Flags modules that specify Option Base 1.
Implicit array lower bound is 0 by default, and Option Base 1 makes it 1. While compelling in a 1-based environment like the Excel object model, having an implicit lower bound of 1 for implicitly-sized user arrays does not change the fact that arrays are always better off with explicit boundaries. Because 0 is always the lower array bound in many other programming languages, this option may trip a reader/maintainer with a different background.
Flags parameters that are passed by reference (ByRef), but could be passed by value (ByVal).
Explicitly specifying a ByVal modifier on a parameter makes the intent explicit: this parameter is not meant to be assigned. In contrast, a parameter that is passed by reference (implicitly, or explicitly ByRef) makes it ambiguous from the calling code's standpoint, whether the procedure might re-assign these ByRef values and introduce a bug.
Warns about identifiers that have names that are likely to be too short, disemvoweled, or appended with a numeric suffix.
Meaningful, pronounceable, unabbreviated names read better and leave less room for interpretation. Moreover, names suffixed with a number can indicate the need to look into an array, collection, or dictionary data structure.