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 features will be announced as \"new\" when they are merged into the [master] branch. Until then, they are only available in pre-release builds.
Warns about late-bound WorksheetFunction calls made against the extended interface of the Application object.
An early-bound, equivalent function exists in the object returned by the Application.WorksheetFunction property; late-bound member calls will fail at run-time with error 438 if there is a typo (a typo fails to compile for an early-bound member call); given invalid inputs, these late-bound member calls return a Variant/Error value that cannot be coerced into another type. The equivalent early-bound member calls raise a more VB-idiomatic, trappable runtime error given the same invalid inputs: trying to compare or assign a Variant/Error to another data type will throw error 13 "type mismatch" at run-time. A Variant/Error value cannot be coerced into any other data type, be it for assignment or comparison.
This inspection will only run if the Excel library is referenced.
Locates arguments passed to functions or procedures for object parameters which the do not have a compatible declared type.
The VBA compiler does not check whether different object types are compatible. Instead there is a runtime error whenever the types are incompatible.
Warns about parameters passed by value being assigned a new value in the body of a procedure.
Debugging is easier if the procedure's initial state is preserved and accessible anywhere within its scope. Mutating the inputs destroys the initial state, and makes the intent ambiguous: if the calling code is meant to be able to access the modified values, then the parameter should be passed ByRef; the ByVal modifier might be a bug.
Indicates that the value of a hidden VB attribute is out of sync with the corresponding Rubberduck annotation comment.
Keeping Rubberduck annotation comments in sync with the hidden VB attribute values, surfaces these hidden attributes in the VBE code panes; Rubberduck can rewrite the attributes to match the corresponding annotation comment.
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.
Locates indexed default member calls for which the corresponding object does not have a suitable suitable default member.
The VBA compiler does not check whether the necessary default member is present. Instead there is a runtime error whenever the runtime type fails to have the default member.
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.
Identifies empty module member blocks.
Methods containing no executable statements are misleading as they appear to be doing something which they actually don't. This might be the result of delaying the actual implementation for a later stage of development, and then forgetting all about that.
Flags uses of an empty string literal ("").
Standard library constant 'vbNullString' is more explicit about its intent, and should be preferred to a string literal. While the memory gain is meaningless, an empty string literal still takes up 2 bytes of memory, but 'vbNullString' is a null string pointer, and doesn't.