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 Hint
to Error
.
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!
This tab lists all items found in the .xml documentation assets from the latest pre-release build. To modify this content, a pull request must be merged into the [next] branch.
Flags uses of an empty string literal ("").
Default severity: Warning
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.
Identifies empty 'While...Wend' blocks that can be safely removed.
Default severity: Warning
Dead code should be removed. A loop without a body is usually redundant.
Flags publicly exposed instance fields.
Default severity: Suggestion
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.
Locates instances of member calls made against the result of a Range.Find/FindNext/FindPrevious method, without prior validation.
Default severity: Warning
Range.Find methods return a Range object reference that refers to the cell containing the search string; this object reference will be Nothing if the search didn't turn up any results, and a member call against Nothing will raise run-time error 91.
This inspection will only run if the Excel library is referenced.
Locates public User-Defined Function procedures accidentally named after a cell reference.
Default severity: Warning
Another good reason to avoid numeric suffixes: if the function is meant to be used as a UDF in a cell formula, the worksheet cell by the same name takes precedence and gets the reference, and the function is never invoked.
This inspection will only run if the Excel library is referenced.
Warns when a user function's return value is discarded at all its call sites.
Default severity: Warning
A 'Function' procedure normally means its return value to be captured and consumed by the calling code. It's possible that not all call sites need the return value, but if the value is systematically discarded then this means the function is side-effecting, and thus should probably be a 'Sub' procedure instead.
Warns when a user function's return value is not used at a call site.
Default severity: Warning
A 'Function' procedure normally means its return value to be captured and consumed by the calling code.
Warns about host-evaluated square-bracketed expressions.
Default severity: Warning
Host-evaluated expressions should be implementable using the host application's object model. If the expression yields an object, member calls against that object are late-bound.
Flags identifiers that use [Systems] Hungarian Notation prefixes.
Default severity: Suggestion
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.
Identifies Functions or Properties referenced by the TruePart(second argument) or FalsePart(third argument) of the IIf built-in function.
Default severity: Warning
All arguments of any function/procedure call are always evaluated before the function is invoked so that their respective values can be passed as parameters. Even so, the IIf Function's behavior is sometimes mis-interpreted to expect that ONLY the 'TruePart' or ONLY the 'FalsePart' expression will be evaluated based on the result of the first argument expression. Consequently, the IIf Function can be a source of unanticipated side-effects and errors if the user does not account for the fact that both the TruePart and FalsePart arguments are always evaluated.
Flags invalid Rubberduck annotation comments.
Default severity: Error
Rubberduck is correctly parsing an annotation, but that annotation is illegal in that context.
Identifies class modules that define an interface with one or more members containing a concrete implementation.
Default severity: Suggestion
Interfaces provide an abstract, unified programmatic access to different objects; concrete implementations of their members should be in a separate module that 'Implements' the interface.
Locates unqualified Worksheet.Range/Cells/Columns/Rows member calls implicitly referring to ActiveSheet.
Default severity: Warning
Implicit references to the active worksheet (ActiveSheet) rarely mean to be working with *whatever worksheet is currently active*. By explicitly qualifying these member calls with a specific Worksheet object, the assumptions are removed, the code is more robust, and will be less likely to throw run-time error 1004 or produce unexpected results when the active sheet isn't the expected one.
This inspection will only run if the Excel library is referenced.
Locates unqualified Workbook.Worksheets/Sheets/Names member calls that implicitly refer to ActiveWorkbook.
Default severity: Warning
Implicit references to the active workbook rarely mean to be working with *whatever workbook is currently active*. By explicitly qualifying these member calls with a specific Workbook object, the assumptions are removed, the code is more robust, and will be less likely to throw run-time error 1004 or produce unexpected results when the active workbook isn't the expected one.
This inspection will only run if the Excel library is referenced.
Highlights implicit ByRef modifiers in user code.
Default severity: Hint
VBA parameters are implicitly ByRef, which differs from modern VB (VB.NET) and most other programming languages which are implicitly ByVal. So, explicitly identifing VBA parameter mechanisms (the ByRef and ByVal modifiers) can help surface potentially unexpected language results. The inspection does not flag an implicit parameter mechanism for the last parameter of Property mutators (Let or Set). VBA applies a ByVal parameter mechanism to the last parameter in the absence (or presence!) of a modifier. Exception: UserDefinedType parameters must always be passed as ByRef.
Locates unqualified Workbook.Worksheets/Sheets/Names member calls inside workbook document modules, that implicitly refer to the host workbook.
Default severity: Warning
Implicit references inside a workbook document module can easily be mistaken for implicit references to the active workbook (ActiveWorkbook), which is the behavior in all other module types. By explicitly qualifying these member calls with 'Me', the ambiguity can be resolved. If the intent is to actually refer to the active workbook, qualify with 'ActiveWorkbook' to prevent a bug.
Locates unqualified Worksheet.Range/Cells/Columns/Rows member calls inside worksheet modules, that implicitly refer to the containing sheet component.
Default severity: Warning
Implicit references inside a worksheet document module can easily be mistaken for implicit references to the active worksheet (ActiveSheet), which is the behavior in all other module types. By explicitly qualifying these member calls with 'Me', the ambiguity can be resolved. If the intent is to refer to the active worksheet, qualify with 'ActiveSheet' to prevent a bug.
Identifies the use of non-indexed default member accesses.
Default severity: Warning
Default member accesses hide away the actually called member. This is especially misleading if there is no indication in the expression that such a call is made and can cause errors in which a member was forgotten to be called to go unnoticed.
Warns about constants that don't have an explicitly defined type.
Default severity: Warning
All constants have a declared type, whether a type is specified or not. The implicit type is determined by the compiler based on the value, which is not always the expected type.
Highlights implicit Public access modifiers in user code.
Default severity: Hint
In modern VB (VB.NET), the implicit access modifier is Private, as it is in most other programming languages. Making the Public modifiers explicit can help surface potentially unexpected language defaults.