What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
  Tip: VB 6 Coding Style  

In general, it's more important to have some coding styles than to use a particular set of rules. Code that is consistent is easier to read, understand, debug, and maintain no matter what rules you use.

However, it amazes me how many developers seem to have no rules or rules that are inconsistent and contradictory. In one very large (56,000 line) project, I've seen people using arbitrary indentation, no comments, improper variable naming (for example, using an "m" prefix that normally means "module-level" for local variables), and so forth.

So here are the rules that I generally use. Adopt the ones that makes sense to you and replace the others. Note that these are the rules that I use for Visual Basic 6. I use slightly different rules for other languages, including VB .NET.

  • Indentation: Indent 4 spaces to show scope. Indent within a subroutine, loop, or If Then block as in the following:
        Private Sub MySub()
        Dim i As Integer
            For i = 1 To 10
                Debug.Print i
            Next i
        End Sub
  • Make sure indentation lines up block start and end statements. For example, make sure the If, Then, Else, and End If statements in a block all line up.
  • Declare variables at the beginning of a subroutine at the same level of indentation as the Sub statement. (A lot of people prefer indent the declarations. Whatever you prefer. Just pick one. Note that VB .NET indents them for you whether you like ot or not.)
  • Use Option Explicit and Option Strict.
  • Declare each variable on a separate line.
  • Prefix module-level variables with "m_" and use "Pascal Case" (capitalize the first letter of each word) as in m_NumEmployees.
  • Prefix global-level variables with "g_" and use "Pascal Case" as in g_NumEmployees.
  • Name constants in ALL CAPS with underscores as in MAX_EMPLOYEES.
  • Specify a data type for all variables and constants as in:
        Private Const MAX_EMPLOYEES As Long = 100
  • Name routine-local variables in lower case with underscores as in num_employees.
  • Use Pascal case for subroutine, function, property, and other routine names as in NumEmployees().
  • Always specify one of Private, Public, etc. whenever those are allowed. I.e. don't declare a subroutine with just Sub, use Private or Public to make its scope obvious.
  • Use type prefixes on control names as in picEmployee (a PictureBox) and lblResult (a Label).
  • Do not use type prefixes (aka Hungarian notation) for other variables.
  • Make variable names obvious enough that you don't miss Hungarian notation.
  • Use a comment at the beginning of every module explaining what its purpose is.
  • Use a comment before every routine explaining what the routine does. Explain parameters and return values.
  • Use liberal comments within the code to explain what it is doing.
  • Do not use GoTo.
  • Do not use IIF. It's confusing and If Then Else is actually faster.
  • Do not use the : character to place more than one statement on a single line.
  • If a single-line If Then statement is long, make it a multi-line If Then End If statement so it's easier to read.
  • Don't try to make anything do too many things. For example, Visual Basic's Line command draws lines or rectangles, optionally specifying the drawing color and whether the rectangle should be filled. This should have been at least two routines, Line and Rectangle.
  • When you use error handling code with an On Error GoTo statement, always place an Exit Sub statement immediately before the error handler. Never allow the code to drop into the error handling code. This makes the code run in a special error handling mode and can be quite confusing.
  • Use Debug.Assert to test for conditions that should not occur. This lets you catch bugs early and easily.
  • If you catch an error, check for all errors not just the ones you expect. Use Debug.Assert to catch those you don't expect.
  • In a Select Case statement, use a Case Else to catch unexpected conditions. If you don't think the condition should ever occur, use Debug.Assert to detect it.

Here's some commented code by WJK showing some of his standards.

Private Sub DoesSomething(inString$, inInteger%) 
Dim Integer%, String$
    ' I always use the variable types
    ' I know people disagree with this.
    ' I find it useful and better for me.
    ' Throughout the code I use the symbol.
    ' Always be aware of variable type.
    ' I do not use the variant variable type very often.
    ' In addition I use gVar to indicate Global Variables
    ' pVar to indicate module level public variables
    ' I always use txtTextBox, lblLabel, cbCheckbox
    ' etc. for controls

    ' An error statement is required at start of subroutine after Dim
    ' statement. Either format depending on subroutine, errs always handled.
    On Error Resume Next
    On Error GoTo DoesSomething_Error 
    ' Name of err statement is always:
    '     subroutine_name+_Error

    ...sub code here...

    Exit Sub

    ' Labels are always to the left. Try to limit goto labels to one 
    ' per subroutine... Goto statement can usually be avoided.

    ' I have some global err handlers, but many subs use this format.
    Select Case Err.Number
        Case xxx  ' This handles specific occurrences, I try to write code to handle 
                  ' before error occurs, code executes faster when you do this. 

        Case Else ' Always an else case for handling most err types.
    End Select

    Resume Next
End Sub

And here are some other tips by WJK.

  • Always try to build a reusable subroutine to accomplish a given task. Never write the same inline code over and over. This makes your code easier to maintain and update (fix one, you fix all)
  • I like the use of the : character only when used with a short if statement:
        IF A=B Then B=C : A=C
  • The inline if statement can be of tremendous use.
        .Fields("Labor_Total_Cost") = Round((.Fields("Quantity") * _
            IIf(.Fields("Labor"), 1, 0) * .Fields("Labor_Unit_Price") * _
            .Fields("THE_FACTOR") * Currency_Value * gCCI_Labr), 2)
    The inline if statement can eliminate having many additional intermediate variables. If it can be done without inline if statements.... I do it that way.
  • Working with record sets, I almost never use the notation:
        recordset.fields(1) = xxxx
    Instead I use:
        recordset.fields("FieldName")= xxxx
    It makes the code self documenting.

I'll add more to this list later.

For more tips and tricks for development, see my book Prototyping With Visual Basic.

Email me your suggestions and I'll consider adding them to the list.


Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.