Coding Standards (Article)

Category:
Miscellaneous
Type:
Snippets
Difficulty:
Beginning

Author: Phil Fresle

Version Compatibility: Visual Basic 5

More information:
This is an article describing the coding standards rules in the author's company, Frez Systems Limited. Though some of the standards apply only to this company, most of them reflect good practice in general. Even if you don't use these standards, it is a good idea to folloow some standard of consistency in variable naming, commenting, formatting code, etc., and this article can give you an idea of what standards to use.

Instructions: 

Visual Basic Coding Standards

Copyright 2000 Frez Systems Limited

Last updated 17-Apr-2000

Introduction
Naming Conventions
Use of Variables, Procedures and Constants
Commenting Code
Formatting Code
Other Coding Rules
Sample Boilerplates
Sample Code Containing Error Handling
Further Reading


Introduction

These are the Visual Basic coding standards used by Frez Systems Limited. Programmers working for Frez Systems Limited are required to work to these standards unless a client has their own standards that they require to be adopted.

These standards are being published on the web to help other programmers who may be in search of a starting point to their own set of coding standards. If you decide to use these standards as your own or part of your own you should include an acknowledgement to Frez Systems Limited in the text. You are forbidden from publishing these standards in order to make a profit.

Where the programmer decides to deviate form the standards this must be for a good reason that must be documented within the code as a comment.

Where code is imported, for instance, from the Visual Basic Windows API Viewer or from MSDN, it is NOT a requirement to change the code to reflect these standards. Although, where it is a sizeable piece of code, comments should be included stating that it is imported and from where it was imported.

These standards only apply to new work, it is not a requirement that they be applied to existing code.


Naming Conventions

Providing a standard for naming variables, constants, functions, controls and modules makes your projects and code easier to follow by other programmers following the same standard.

Variable Naming

Variable names shall describe their use, shall be in mixed case with an initial upper case character for each word, and shall have 'Hungarian' prefixes that describe their type and scope. Abbreviations shall be avoided, but where they are used they are to be used consistently throughout the entire application.

Hungarian prefixes not only identify the type of a variable but also have the advantage of avoiding confusion between variables and functions, methods or properties.

Hungarian Type Prefixes:

Data TypePrefixExample
Boolean b bIsValid
Byte byt bytAge
Currency cur curPrice
Date (and Time) dt dtStart
Double d dScale
Integer i iCounter
Long l lHighCounter
Single (floating point) f fSize
String s sDepartmentName
Variant vnt vntUnknown
Object o oCustomer
Collection col colCustomers
User Defined Type udt udtPoint
Enum enm enmGender

Arrays shall have no special prefix, but shall have a plural name, or a name ending Array, for instance, sNames or lCustomersArray.

Scope Prefixes:

ScopePrefixExample
Static s_ s_bIsValid
Module m_ m_bIsValid
Global g_ g_IsValid

Visual Basic control names will have a three character Hungarian prefix as set out in the back of the Visual Basic Programmer's Guide, for example txt is the prefix for a textbox.

In addition, variables that point to a form will be prefixed 'frm', and general purpose variables for controls will be prefixed 'ctl'.

Constant Naming

Constants will have names that describe their use, and they shall be in upper case with underscores separating each word. There will be no requirement to specify a Hungarian type prefix, but the same prefixes as variables shall be used to show module and global scope.

Enumeration names and member names shall be prefixed with a the 'fsl' company prefix to set them apart from Visual Basics own enumerations, for example:
ÿÿÿÿPublic Enum fslGender
ÿÿÿÿÿÿÿÿfslUnknown
ÿÿÿÿÿÿÿÿfslMale
ÿÿÿÿÿÿÿÿfslFemale
ÿÿÿÿEnd Enum

Procedure Naming

Procedure shall have mixed case descriptive names where the initial character of each word is in upper case. The names shall only exceptionally contain abbreviations, and where abbreviations are used they shall be used consistently throughout the application.

Module Naming

Modules, class, form and standard shall have descriptive names. They shall also have a one character prefix in upper case; F for forms, M for standard modules, and C for class modules. This in particular helps distinguish the name of form modules from variables referencing a form instance.

Abstract interfaces shall be prefixed with a single upper case I character.


Use of Variables, Procedures and Constants

Variables

Variables shall be explicitly declared, and to this end Option Explicit is to appear at the top of all modules.

Object variables are not to be declared 'As New...', rather they will be declared as the type of object and when an instance is required it will be created with the 'Set ... = New ...' or by using CreateObject as appropriate.

The generic form variable that is automatically created by VB with the same name as the form modules is not to be used, rather, whenever an instance of a form is required a specific variable declared as the form type will be used.

Variables shall be declared at the narrowest scope possible. Global scope modules are to be avoided.

Local variables shall be declared at the top of a procedure, not within the body.

The Variant type shall only be used when no other more specific type is possible.

Variables shall have a focused use. They shall not be declared once and used for several different purposes.

String variables shall be concatenated with the ampersand character (i.e. & not +)

When naming boolean variables, the positive rather than the negative form shall be preferred, i.e. bIsValid rather than bIsNotValid.

Procedures

Procedures shall have an appropriate clearly defined scope (Public, Private or Friend) and not rely on the default setting.

Procedures shall have as few exit points as possible; Exit Function/Sub and Property are to be avoided unless it improves the readability.

Procedures shall have robust exit code where object references are explicitly tidied up rather than relying on Visual Basic to clean up as they go out of scope.

Parameters shall have a specified data type.

Data will be passed to and from procedures with parameters rather than module or global scope variables.

Parameters with a small range of values shall be declared with an enumeration type.

Where parameters are not to be changed they shall be declared ByVal unless there is some performance reason to declare them ByRef.

Constants

System constants and enumerations shall be used wherever possible, for example, vbMinimized.

Constants shall not be declared in multiple places, rather they shall be declared at a higher scope.

Constants shall always be used in place of 'magic numbers', the exception to this being the initialisation of variables to 0 or 1 (i.e. initialising a loop counter).

Constants shall be used when referring to elements in a control array, for example, txtName(FIRST_NAME).Text


Commenting Code

Comments shall specify what the purpose of the code is, it shall not simply repeat the code.

All deviations from coding standards or good programming practice shall have a comment specifying the reasons why.

Comments shall be indented to the same level as the code that follows them.

End-of-line comments shall be avoided, the exception being in the declaration section if a comment for a variable declaration is required.

Comments shall be specified with a apostrophe not with the antiquated Rem statement.

Every procedure and module shall have a boilerplate that descibes it purpose and parameters.

Solid comment lines (for instance '********) are not to be used except in module or procedure boilerplates.

Document all decision and loop structures.


Formatting Code

The indent tab setting in the Visual Basic Options shall be left at the default setting of 4 spaces.

Indenting and white space shall be used to make the code more readable, like the paragraphs of a book.

No more that one statement shall appear on a single line.

Use the continuation character to split long lines to make them more readable. The continuation lines shall be indented.

Indent code as follows:

  • Between an If statement and its End If, Else or ElseIf.
  • Between an Else and its End If.
  • Between an ElseIf and its Else or End If.
  • Between a Select statement and its End Select statement.
  • Between each Case statement in a Select.
  • Between a Do statement and its Loop.
  • Between a With statement and its End With.
  • Between a For statement and its Next.
  • Between an Edit or AddNew method and its Update or CancelUpdate.
  • Between the start and end of a transaction.
  • Within the declaration section to show subordination, for instance between a Type and its End Type.

Other Coding Rules

Every procedure shall contain error handling to capture and re-raise or report errors.

The most specific type of object variable shall be used in a For Each..Next loop.

Always include a Case Else in Select Case structures.

Split an If statement to use an End If even where there is only one statement to execute.

Never compare a boolean for equality with True or False.

Use parenthesis to improve readability even when they are strictly not required.

Use upper case letters for GoTo labels.

Use GoTo only where it improves readability.

Do not use GoSub.

Do not use default properties, rather specify them explicitly, for example txtName.Text = sName

The reference counter used in a For..Next loop shall not be used after the loop has finished.

The antiquated While..Wend loop shall not be used.

Compile On Demand is not to be used in the Visual Basic options.

DoEvents shall be avoided unless required, specifically, where a control or form is to be refreshed the Refresh method shall be used in preference to DoEvents.


Sample Boilerplates

Module Boilerplate:

'*******************************************************************************
' MODULE:ÿÿÿÿÿÿÿFMain
' FILENAME:ÿÿÿÿÿC:\Project\FMain.frm
' AUTHOR:ÿÿÿÿÿÿÿPhil Fresle
' CREATED:ÿÿÿÿÿÿ15-Apr-2000
' COPYRIGHT:ÿÿÿÿCopyright 2000 Frez Systems Limited. All Rights Reserved.
'
' DESCRIPTION:
' ***Description goes here***
'
' MODIFICATION HISTORY:
' 1.0ÿÿÿÿÿÿÿ15-Apr-2000
'ÿÿÿÿÿÿÿÿÿÿÿPhil Fresle
'ÿÿÿÿÿÿÿÿÿÿÿInitial Version
'*******************************************************************************

Procedure Boilerplate:

'*******************************************************************************
' GetUserName (FUNCTION)
'
' PARAMETERS:
' (In) - lUserID - Long -
'
' RETURN VALUE:
' String -
'
' DESCRIPTION:
' ***Description goes here***
'*******************************************************************************


Sample Code Containing Error Handling

Private Const MODULE_NAME As String = "SomeModule"

Private Sub SomeProcedureName()
ÿÿÿÿ Dim lErrNumberÿÿÿÿÿÿAs Long
ÿÿÿÿ Dim sErrSourceÿÿÿÿÿÿAs String
ÿÿÿÿ Dim sErrDescription As String

ÿÿÿÿ Const PROCEDURE_NAME As String = "SomeProcedureName"

ÿÿÿÿ On Error GoTo ERROR_HANDLER

ÿÿÿÿ '**** Procedure's code (that may result in errors) goes here

TIDY_UP:
ÿÿÿÿ On Error Resume Next

ÿÿÿÿ '**** Place code to tidy up object references here where we don't care about errors

ÿÿÿÿ ' Re-raise if we found an error
ÿÿÿÿ If lErrNumber <> 0 Then
ÿÿÿÿÿÿÿÿ On Error GoTo 0
ÿÿÿÿÿÿÿÿ Err.Raise lErrNumber, sErrSource, sErrDescription
ÿÿÿÿ End If
Exit Sub

ERROR_HANDLER:
ÿÿÿÿ lErrNumber = Err.Number
ÿÿÿÿ sErrDescription = Err.Description
ÿÿÿÿ sErrSource = FormatErrorSource(Err.Source, MODULE_NAME, PROCEDURE_NAME)
ÿÿÿÿ Resume TIDY_UP
End Sub

Public Function FormatErrorSource(ByVal sErrSource As String, _
ÿÿÿÿ ByVal sModule As String, ByVal sFunction As String) As String

ÿÿÿÿ Static s_sDefaultErrorSource As String

ÿÿÿÿ On Error Resume Next

ÿÿÿÿ If s_sDefaultErrorSource = "" Then
ÿÿÿÿÿÿÿÿ Err.Raise vbObjectError
ÿÿÿÿÿÿÿÿ s_sDefaultErrorSource = Err.Source
ÿÿÿÿÿÿÿÿ Err.Clear
ÿÿÿÿ End If

ÿÿÿÿ If sErrSource = s_sDefaultErrorSource Then
ÿÿÿÿÿÿÿÿ FormatErrorSource = App.Title & "." & sModule & "." & sFunction
ÿÿÿÿ Else
ÿÿÿÿÿÿÿÿ FormatErrorSource = sErrSource & vbCrLf _
ÿÿÿÿÿÿÿÿÿÿÿÿ & App.Title & "." & sModule & "." & sFunction
ÿÿÿÿ End If
End Function


Further Reading

Coding Techniques and Programming Practices, by Rob Caron, http://msdn.microsoft.com/library/techart/cfr.htm

The Basics of Programming Model Design, by Dave Stearns, http://msdn.microsoft.com/library/techart/msdn_basicpmd.htm

Visual Basic Programming Standards, by Jim Karabatsos, http://www.gui.com.au/jkcoding.htm

C++ Coding Standards, by Todd Hoff, http://www.possibility.com/Cpp/CppCodingStandard.html

Practical Standards for Microsoft Visual Basic, by James D. Foxall, Published by MS Press, ISBN 0-7356-0733-8

Visual Basic Programmer's Guide

.