Add guidance on duplicate Dim declarations in VBA
Clarify that VBA uses procedure-level scope and declaring the same variable more than once causes compile errors. Include examples of correct and incorrect patterns. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,62 @@ description: VBA (Visual Basic for Applications) coding standards for Excel, Wo
|
||||
- **Use `vbNullString` instead of `""`** for empty string assignment; use `Len(s) = 0` to check emptiness — both are faster than comparing against `""`.
|
||||
- **Use `vb` string constants** instead of `Chr()` calls: `vbTab`, `vbLf`, `vbCr`, `vbNewLine` (fastest), `vbNullChar`.
|
||||
|
||||
### No Duplicate `Dim` Declarations Within a Procedure
|
||||
|
||||
VBA uses **procedure-level scope** — a variable declared anywhere inside a Sub/Function is scoped to the entire procedure. Declaring the same variable name more than once (even in separate `If/Else` branches or nested loops) causes a **compile error**.
|
||||
|
||||
**Rule: declare every variable exactly once, at the top of the procedure.**
|
||||
|
||||
```vb
|
||||
' ❌ Compile error — same name declared twice in different branches
|
||||
Sub BadExample()
|
||||
If condition Then
|
||||
Dim x As Integer ' first declaration
|
||||
x = 1
|
||||
Else
|
||||
Dim x As Integer ' DUPLICATE — compiler rejects this
|
||||
x = 2
|
||||
End If
|
||||
End Sub
|
||||
|
||||
' ✅ Correct — declared once at the top, assigned freely in any branch
|
||||
Sub GoodExample()
|
||||
Dim x As Integer ' single declaration
|
||||
|
||||
If condition Then
|
||||
x = 1
|
||||
Else
|
||||
x = 2
|
||||
End If
|
||||
End Sub
|
||||
```
|
||||
|
||||
The same rule applies to loop variables reused across multiple `For Each` loops:
|
||||
|
||||
```vb
|
||||
' ❌ Compile error — rawMat declared inside two separate loops
|
||||
For Each rawMat In rawMaterials ' implicit Dim inside loop
|
||||
allRawMaterials.Add rawMat
|
||||
Next rawMat
|
||||
|
||||
For Each rawMat In allRawMaterials ' duplicate Dim — compile error
|
||||
' ...
|
||||
Next rawMat
|
||||
|
||||
' ✅ Correct — declare once at the top, reuse freely
|
||||
Dim rawMat As Variant
|
||||
|
||||
For Each rawMat In rawMaterials
|
||||
allRawMaterials.Add rawMat
|
||||
Next rawMat
|
||||
|
||||
For Each rawMat In allRawMaterials
|
||||
' ...
|
||||
Next rawMat
|
||||
```
|
||||
|
||||
**Tip:** A quick way to catch duplicates is to search for `Dim <varname>` within the same procedure. With `Option Explicit` enabled, the compiler will also surface this error on the first compile attempt.
|
||||
|
||||
---
|
||||
|
||||
## Parameters & Scope
|
||||
@@ -104,6 +160,7 @@ Sheet1.Range("A1:D500").Value = arData ' one write
|
||||
|---|---|
|
||||
| `Option Explicit` in every module | Prevents undeclared-variable bugs |
|
||||
| Descriptive names + Hungarian prefixes | Readability & self-documentation |
|
||||
| Each variable declared **once**, at procedure top | Duplicate `Dim` = compile error |
|
||||
| `ByVal`/`ByRef` always explicit | No silent side effects |
|
||||
| Custom `GoTo ErrorHandler`, not `Resume Next` | Errors surface instead of hiding |
|
||||
| `With…End With` for repeated object refs | Speed + clarity |
|
||||
@@ -111,4 +168,4 @@ Sheet1.Range("A1:D500").Value = arData ' one write
|
||||
| `vbNullString` / `Len()` for strings | Faster than `""` comparison |
|
||||
| Arrays for bulk range I/O | Orders-of-magnitude speed gain |
|
||||
| No `Option Base 1` or `Option Compare Text` | Predictable defaults |
|
||||
| No `GoTo` except for error handler label | Structured, readable flow |
|
||||
| No `GoTo` except for error handler label | Structured, readable flow |
|
||||
Reference in New Issue
Block a user