Visual Basic Naming Conventions in VB5 & VB6


The purpose of this document is to describe a set of coding conventions (a frame-work if you will) which can be used for your Visual Basic projects. This standard uses a combination of Hungarian notation and information from other sources such as TMS’s VB Vogue, and various Microsoft publications. Using these standards as a platform, additions and modifications were performed by software developers in real-world applications. Adhering to a standard like this will ensure uniform development across your code, and across applications.

Naming Conventions


Type Information
Hungarian type prefixes have two parts: a base type to represent the base data type and a modifier to denote an aggregate type. An example of a base-type prefix is n, which denotes an integer, while adding the a modifier to the base type denotes an array of integers.
   Dim nCount                    As Integer
   Dim anCounters(1 to 5)        As Integer
The variable name itself starts with an upper case character to show where the prefix stops and the variable name starts. There may be cases where you would need to use more than one modifier, as in the case of a multi-dimensional array.
   Dim aanMultiTable (1 to 5, 1 to 10)  As Integer

The letter ‘a’ is the only single type aggregate supported by Visual Basic, so it will be the only type modifier listed here. (note: a collection is not single type and is denoted by the prefix ‘col’).

Calls made to windows API functions are commonly given different naming conventions such as sz and LPSTR. These standards are used in MS Windows documentation and for simplicity and reference should not be modified. You may also see p used to denote a pointer and pcb used to denote the address of a callback function.

For variables defined with user-defined types and classes, the base-type characters udt and c are used. The upper case C is used to name a class module, and any object created from that class is named with a lower case c. User-defined types and variables instantiated from them are prefixed with UDT and udt, respectively.
   Dim cNewUser                  As New CPerson
   Dim udtNewUser                As New UDTPerson
Menus are named with the type prefix mnu, but the names are aggregated to show the actual structure of the menu. For example, the About item of the Help menu would be named:
   mnuHelpAbout
   mnuFileOpen


Scope Information
There are also prefixes used to denote an object’s scope. The scope prefixes come between the type prefix and the object name, so you need to make sure that they start with an uppercase and end with a lowercase letter. This way the scope will stand out from the type prefix and the object itself. Examples some scope modifiers are Gb, for global, and Pi for private.

Variables
Variables are named in the following manner:



The is simply the variable name written with mixed case as described earlier. It is considered bad practice to name a variable using the underscore character ‘_’. This character is more commonly used for sub and function names.

Local Variables do not have a scope prefix. Here are some examples of local variable defenitions:
   Dim nCount        As Integer
   Dim sQuery        As String
   Dim cUser         As New Cperson
Private variables defined at the module level have Pi as a scope prefix:
   Private nPiCount              As Integer
   Private sPiQuery              As String
   Private cPiUser               As New Cperson
Public variables defined at the module level of a standard module (i.e. BAS file) have the scope prefix Gb:
   Public nGbCount               As Integer
   Public sGbQuery               As String
   Public anGbThisArray()        As Integer

NOTE: Public variables defined at the module level of classes or Forms, are considered Properties and do not have and scope or type prefix.

Functions and Subroutines
Public functions and subroutines have scope prefixes in the same way that variables do. Public and private functions also use the type prefix to show what type of value they return. The rules for choosing the type and scope prefix are the same as for variables.

Private subroutines and functions do NOT require scope prefixes. Here are some examples of private subroutines:
   Private Sub ClearGrid()

   Private Sub DeleteImportantInfo()
And Private functions:
   Private Function nNextItem() as Integer

   Private Function sGetPath (byVal sFileName As String) As String

Global subroutines are prefixed in exactly the same way that global variables are:
   Public Sub GbClearGrid()
   Public Function nGbNextValue() As Integer

Public functions and subroutines defined in classes and forms are methods and do not have type or scope prefixes.

Protected form and class properties, Property Let, Property Set, and Property Get routines do not have scope of type prefixes.

Declaring Windows API functions.
Use the Alias keyword to add the prefix Win. For example, CallWindowProc becomes WinCallWindowProc. When declaring other DLL functions, use the prefix Dll.

Contols and Forms
Prefixes for controls and forms are given at the end of this document. Forms are named in the same manner as controls, though a form behaves like, and basically is, a class. Forms are named with the prefix frm.
   Dim frmNewBrowser As New frmSaleBrowser


Constants
Constants are named in all uppercase letters with no type or scope prefix. Arbitrary prefixes, possibly separated by and ‘_’ (since it is all uppercase) can show the relationship between contants.
   Const DEFAULT_KEY             As String = "VBMAHJONGG"
   Const DEFAULT_SECTION         As String = "DATABASE INFO"


Type and Class Definitions
Type names are prefixed with UDT for the declaration and for the dimensioned variable, the lowercase udt is used. This rule applies to classes as well, using uppercase C and lowercase c respectively.
   Type UDTPerson
      sFullName   As String
      nSalary     As Integer
   End Type

And in use:
    Dim udtNewUser          As UDTPerson
    Dim cNewOpp             As New Copportunity


Coding Conventions

This section contains several conventions that should be useful when writing code. They are by no means comprehensive, but should nonetheless be seriously considered in development. This section will continue to be developed in order to obtain a complete development guide. The Changing Your Approach subsection talks about four very important rules that you can follow that help you take advantage of VB5/6’s object oriented capability. The Principles subsection gives smaller and more specific suggestions on coding style.

Changing Your Approach
There are three rules (so far) that you can quickly apply to your coding style that will quickly improve its quality. These rules are also a simple way to force yourself to take advantage of VB5/VB6’s Object Oriented Programming capability. These are not necessarily in order of importance, but number one is, in my opinion, extremely important and simple to implement. Some of this information may be repeated in the Principles subsection.
  1. Do not use global variables. This means literally NO global variables. Understanding class modules and the (finally) ability to treat forms as objects in VB5 makes it unnecessary to have any global variables. Why not? Well the short answer is that global variables create a possible dangerous interdependency between different parts of your program. They are also difficult to trace properly. If you need to share information between objects or forms, make that information a property or method of your object, do not use a global variable. A global variable is easy to define and use initially, but they ALWAYS create more problems then they solve in the long term. Some applications have a particular functionality that may seem to lend itself to a small number of global variables. An example of this could be a global instance of a User class. This could be seen as acceptable because the nature of this variable is truly global, in the sense that it could be needed in every part of the application. For the most part, you should never have more global variables than you can count on one hand.
     
  2. Do not use user-defined types. This means anything with the Type statement in it. These structures were quite effectively replaced by classes in VB5. If you have something that is a candidate for a user-defined type, then it is a candidate for a class. Besides classes are more powerful and FUN! There is one exception to this rule, that is if you are calling a DLL that requires a structure.
     
  3. Do not pass function parameters by reference. Unfortunately, the default way in which variables are passed in Visual Basic is by reference. Prefix all of your sub and function parameters with the keyword ByVal. There are a million reasons not to pass by reference, but mainly it is very hard to trace a bad value if a called procedure is (knowingly or unknowingly) modifying your variable in memory.


Principles
Write your code for the reader. In rapid application development clarity is more cost effective than efficiency. Understanding efficiency is important, and should serve as a guide in your coding, however clearly written and documented code is easier to understand and maintain. By today’s standards, processing cycles are extremely inexpensive, so highly efficient and cryptic code can cost more in the later phases of the development life cycle. Here are some high level guidelines:
  • Be verbose rather than terse.
  • Parenthesize _expression to make them clearer.
  • Code for clarity, not efficiency.
  • Limit the scope of variables, constants, functions and subroutines. If you have the choice, always use local objects instead of global ones.
  • Use explicit type conversions (Cint, Cstr, and so on) when assigning different variable types.



Some Specifics:

Follow these guidelines when writing your code.
  • Define all variables explicitly. Option Explicit enforces this, and you can force Option Explicit in all objects by checking the Require Variable Declaration under the Tools > Options > Editor.
  • Always specify the upper and lower bounds in an array definition.
  • Define constants, and use them in place of hard-coded numbers in your code.
  • Always use the ByVal and ByRef keywords in the parameter lists of your subroutines and functions. You should generally not use ByRef at all (see Changing Your Approach above)
  • Always use the Private keyword on functions and subroutines that are not used outside of a module.
  • Declare all variables explicitly. Dimensioned variables are variant if no type is supplied but you should always supply a type, even if that type is variant (e.g Dim nX As Integer, Dim vThing as Variant). This also applies to subroutines and functions. Such as Function sTest () as String instead of Function sTest().
  • Do not use implicit type suffixes such as ! and & in variable definitions.
  • In For loops, use Next instead of just next.


Documentation
One of the best sources of documentation is the code itself. If you follow specific coding standards throughout your application and thoroughly comment your code, you are making your program more readable and providing valuable information to yourself and to other programmers that might have to make modifications later.

Formatting
Follow these rules when formatting your code:
  • Indent your code to 4 spaces. This setting is available in the code settings sections available through Tools>Options>Editor.
  • Punctuate your code with blank lines.
  • Keep your procedures to a manageable size, preferably not more than a single screen.
  • Keep your indentation under control, if you are having difficulty remaining within the right margin, you are probably nesting too deeply.
  • Use Parenthesis to enhance the readability of your code. People should be able to tell what a given formula does at first glance.
End-of-Line Comments
End-of-Line comments should be used to annotate variable and constant definitions.
      Const MAX_LINES = 200   'The max lines allowable in grdOne

      Dim nX As Integer       'used to index record counting loop in my VB program!
In-Line Comments
End-of-line comments are usually not needed for annotating your actual code. In general the syntax of VB is readable. In cases where a function or subroutine contains a certain number of logical blocks, you can introduce each block with a separate comment on it’s own line. Use as many lines for the comment as you need, but keep the lines short so that they can be displayed on a VGA monitor without scrolling left and right. End-of-line comments are sometimes helpful to comment ‘Loop’, ‘Next nJ’, ‘Else’ and ‘ElseIf’ in order to clarify the expected condition, or identify the top of the loop.

Use comments to explain the code, not echo it; if your comments become very involved, consider restructuring the code. For more complicated subroutines, it may be more informative to move complicated documentation into the routine’s header documentation.

File Headers
Every module should have a header that sits as a comment in the module’s defenitions area. This header identifies the module and summarizes the external interfaces to it. Here is an example:
'***************************************************************
'* Module:        Utilities
'*
'* File Name:     util.bas
'*
'* Author:        Orville Chomer
'*
'* Description:
'*
'* This module contains all of the generic utilities used
'* in the cool Chomer.com application.
'*
'*
'*
'* Revisions:
'*---date------rev. by--------------brief descr.-----------------
'*  1.27.2006   O.Chomer     added instance checking
'*
'*
'***************************************************************


Function and Subroutine Headers
A function header is a comment that describes what the function does and summarizes its interface. The description should focus on what the function does, although for complicated or longer functions it might be appropriate to summarize the how as well.

Here is an example of a function header.
'***************************************************************
'* Synopsis:   Initialize the Opp Browser form
'*
'*
'* Parameters:
'*----name------------------[I/O]--description------------------
'*
'*
'* Nonlocal Data:
'*----name------------------[I/O]--description------------------
'*
'*
'*
'* Description:
'*  - init forms and private variables
'*  - init the user selection tree, or load if management
'*  - check user permissions to use the form
'*  - load the grid with current opps
'*
'* > O.Chomer 11/2/05
'***************************************************************

Type Prefixes

This section details the type prefixes to use in you applications. Remember that, in order to be effective, these should be used consistently throughout your code.

Variable Prefixes:

Prefix Data Type
b Boolean
byt Byte
col Collection
cur Currency
dte Date
d Double
hf File handle (Long)
h(...lowercase) Handle to something (long)
n Integer
l Long
o Object
c Object instantiated from a class
f Single
s String
v Variant
hwnd Window handle (Long)

Modifiers and Special Type Prefixes
Table 2
Prefix Data Type
a Array
C Class (not class instance)
udt User defined type
e Enumerated type or instance
p Pointer (used in API calls)
pcb Pointer to a callback function (used with AddressOf)

Data Objects: DAO Prefixes
Table 3
Prefix Visual Basic Data Type
bk SelBookmarks
ct Container
db Database
dc Document
ds Dynaset
er Errors
fld Field
gp Group
idx Index
pa Parameter
qd QueryDef
rs Recordset
rl Relation
ss Snapshot
tbl Table
td TableDef
usr User
wrk Workspace

Data Objects: RDO Prefixes
Table 4 rdoEng rdoEngine rdoEnv rdoEnvironment rdoConn rdoConnection rdoTbl rdoTable rdoCol rdoColumn rdoPrepS rdoPreparedStatement rdoParam rdoParameter rdoRS rdoResultset rdoErr rdoError
Prefix Visual Basic Data Type
Control Prefixes Table 5
Prefix Control Type Description
pnl 3d panel
ani Animation button
chk Checkbox
cbo Combobox/Dropdown Listbox
cmd Command button
crp Crystal Reports Control
dlg Common dialog
com Communications
*cur Currency Control
dat Data control
*dte Date Control
dir Directory listbox
drv Drive listbox
fil File listbox
frm Form
fra Frame
gau Gauge
gra Graph
grd Grid
gbp Group pushbutton
hsb Horizontal scroll bar
img Image
iml ImageList
key Keyboard key status
lbl Label
lin Line
lst listbox
lvw ListView
mpm MAPI message
mps MAPI session
msk Mask TextBox
mci MCI
mnu Menu
ole Ole Client
opt Option button
out Outline Control
bed Pen BEdit
hed Pen HEdit
ink Pen ink
pic Picture
clp Picture clip
pbr ProgressBar
Rdc Remote date control
Rtf RichTextBox
Shp Shape
Sld Slider
spn Spin control
tab SS Tab Control
txt Text box
tim Timer
tbr Toolbar
tvw TreeView
vsb Vertical scroll bar


*dte and cur are also variable prefixes but dte and cur would commonly begin with two letter signifying the third party vendor, for example the cur control could be named fpcurMonthlyTotal.

Data-Bound Control Prefixes
Table 6
Prefix Control Type Description
dbcbo Databound ComboBox/Dropdown ListBox
dblst Databound listbox
dbgrd Databound grid

* These are also used for the Currency and Date variable types, as well as custom or third party currency and date controls.
Copyright © 2003- 2008, Orville Paul Chomer, All Rights Reserved