Jump down to:
If you make any changes to these coding conventions notify the development team of the change!
All classes should have a 3 letter prefix, with the initial letter capitalized, that indicates the kind of class. For example, DlgModelDefinition says that the Model Definition class is a dialog (Dlg) form. The 3 letter prefixes are listed in the following sections.
In addition, some classes which are very closely associated with another class (usually a form) have second 2 letter prefix. This comes between the class prefix and the name, indicating which class they are assocated with. For example, DlgABColumnManager is the Column Manager dialog (Dlg) form attached to the Analysis Browser (AB). The 2 letter prefixes used are as follows:
2-letter prefix | Class associated with |
---|---|
AD | Analysis Details |
BR | Browser (generic) |
CD | Conventional distance sampling engine (properties) |
DD | Design Details |
DE | Data Explorer |
DF | Data Filter (properties) |
DI | Data Import |
DS | Design (properties) |
FM | FitModel (properties) |
ID | Simulation Details |
MD | Model Definition (properties) |
SP | Setup Project |
SD | Survey Details |
When saving classes to file, drop the prefix e.g. form DlgABColumnManager becomes ColumnManager.frm. See Form and Module Filenames below for more details.
All classes that are not standard VB classes and are not user-defined should be fully qualififed. For example:
Dim fldTemp As Field 'No qualifying here as a standard VB class
Dim mofldTemp As MapObjects.Field
Dim flxGrid As New vsFlexLib.vsFlexArray
Form type | Explanation | Prefix | Example |
---|---|---|---|
Dialog form | Modal form, usually with BorderStyle property = Fixed Dialog | Dlg | DlgOpenProject |
Wizard form | Special type of Dialog form that provides an interactive user interface for complex tasks | Wiz | WizDataImport |
MDI parent form | Multiple document interface parent form - only one in the app | Mdi | MdiMain |
Multiple instance form | Child form of the MDI parent where more than one can be shown at once | Mif | MifAnalysisDetails |
Single instance form | Child form of the MDI parent where only one can be shown at once | Sif | SifDataExplorer |
Other (general) form | Anything else - should be very few of these! | Frm | FrmDialogStorage |
Database-specific code modules are prefixed with Dbe, for Database Engine.
All other code modules are prefixed with Mod e.g. ModMain.
Class modules are prefixed with Cls e.g. ClsAnalysisServerInterface.
Classes that are collections have pluralized names e.g. the Analysis Server Interface collection is ClsAnalysisServerInterfaces.
In general, user controls have the prefix Ctl e.g. CtlLabelLine.
However, there are two special subsets of the users controls:
Other classes include, for example, StringBuilder.
Control type | Prefix | Example | Date added |
---|---|---|---|
3D Panel | pnl | pnlGroup | |
ActiveBar (by Data Dynamcs) | bar | barAnalysis | 6/4/98 |
Animated button | ani | aniMailBox | |
Browse dialog (by Common Controls Replacement Program) | bdlg | bdlgBrowse | 14/7/98 |
Chart (by Microsoft) | chrt | chrtResults | 5/7/98 |
Check box | chk | chkReadOnly | |
Combo box, drop-down list box | cbo | cboEnglish | |
Command button | cmd | cmdExit | |
Common dialog | dlg | dlgFileOpen | |
Communications | com | comFax | |
Control (used when the specific type is unknown) | ctr | ctrCurrent | |
Data control | dat | datBiblio | |
Data-bound combo box | dbcbo | dbcboLanguage | |
Data-bound grid | dbgrd | dbgrdQueryResult | |
Data-bound list box | dblst | dblstJobType | |
Directory list box | dir | dirSource | |
Drive list box | drv | drvTarget | |
File dialog (by Common Controls Replacement Program) | fdlg | fdlgOpen | 14/7/98 |
File | file | fileTemp | 11/8/00 |
File list box | fil | filSource | |
FileSystemObject | fso | fsoTemp | 11/8/00 |
FlexArray (by Video Soft) | flx | flxDataSheet | 2/2/98 |
FlexString (by Video Soft) | flxstr | flxstrResults | 17/2/98 |
Folder | fldr | fldrTemp | 11/8/00 |
Frame | fra | fraLanguage | |
Gauge | gau | gauStatus | |
Grid | grd | grdPrices | |
Horizontal scroll bar | hsb | hsbVolume | |
Image | img | imgIcon | |
ImageList | ils | ilsAllIcons | |
ImprintPro (by Far Point) | imp | impDataSheet | 24/2/98 |
Input page (by ljt - group of user controls) | pag | pagModel | 16/3/98 |
Key status | key | keyCaps | |
Label | lbl | lblHelpMessage | |
LabelLine (by ljt) | lal | lalInput | |
Line | lin | linVertical | |
ListBar (by Sheridan Software) | lbr | lbrAnalysisInputs | |
ListItem (by Sheridan Software) | lit | litModel | |
List box | lst | lstPolicyCodes | |
ListView | lvw | lvwHeadings | |
MAPI message | mpm | mpmSentMessage | |
MAPI session | mps | mpsSession | |
Masked edit | mas | masAlpah | |
MCI | mci | mciVideo | |
Menu | mnu | mnuFileOpen | |
MsgDisplay (by ljt) | msg | msgOutput | |
MS Tab | mst | mstFirst | |
Node | nod | nodMember | |
OLE | ole | oleWorksheet | |
Option button | opt | optChoice | |
Outline | out | outOrgChart | |
Input page (by ljt) | pag | pagModel | |
ParseListBox (by ljt) | prslst | prslstLog | |
Pen BEdit | bed | bedFirstName | |
Pen HEdit | hed | hedSignature | |
Pen ink | ink | inkMap | |
Picture | pic | picVGA | |
Picture clip | clp | clpToolbar | |
ProgressBar | prg | prgLoadFile | |
RegExp | rex | rexString | |
Report | rpt | rptQtr1Earnings | |
Ribbon (by Sheridan Software) | rib | ribPlotStyle | |
RichTextBox | rtf | rtfReport | |
Shape | shp | shpCircle | |
Slider | sld | sldScale | |
Spin | spn | spnPages | |
Splitter (by Sheridan Software) | spl | splAnalysisDetails | |
StatusBar | sta | staDateTime | |
StringBuilder | stb | stbCommand | |
Tab (see next) | tab | tabOptons | |
TabStrip | tabs | tabsDefinitions | |
TabPro (by Far Point) | tap | tapDefinitions | |
Text box | txt | txtLastName | |
Timer | tmr | tmrAlarm | |
Tool (by Data Dynamcs) | tool | toolPaste | |
Toolbar | tlb | tlbActions | |
TreeView | tre | treOrganization | |
UpDown | upd | updDirection | |
User Control (unless given specific prefix) | uct | uctInputs | |
VBControlExtender | ctlext | ctlextNew | |
Vertical scroll bar | vsb | vsbRate |
Collection objects should have an ‘s’ added to the prefix, and the variable name should be pluralized. For example:
Dim nodMember As Node
Dim nodsMembers As Nodes
For controls not listed above, standardize on a unique two or three character prefix. Use more than three characters only if needed for clarity.
Once you decide on a new prefix, add it to the table above, write in the date, and notify the development team of the update.
Prefix for the Control:
Type | Prefix |
---|---|
Map | map |
Prefixes for Objects:
Category | Type | Prefix |
---|---|---|
Address Matching | Address | add |
AddressLocation | adl | |
AddressMatcher | adm | |
PlaceLocator | pll | |
Data Access | DataConnection | dcn |
Field | mofld | |
GeoDataset | geo | |
Recordset | morec | |
Statistics | sts | |
Table | tbl | |
TableDesc | tds | |
Map Display | ClassBreaksRenderer | cbr |
DotDensityRenderer | ddr | |
GeoEvent | gev | |
MapLayer | mly | |
ImageLayer | ily | |
LabelRenderer | lbr | |
Symbol | sym | |
TextSymbol | tsym | |
TrackingLayer | tly | |
ValueMapRenderer | vmr | |
Geometric | Ellipse | elp |
Line | molin | |
Point | pnt | |
Polygon | pgn | |
Rectangle | rtg | |
moPlus | ChartRenderer | chrtr |
GroupRenderer | grr | |
LabelPlacer | lbp | |
PathFinder | ptf |
Prefixes for Collections:
Category | Type | Prefix |
---|---|---|
Data Access | Fields | moflds |
GeoDatasets | geos | |
Map Display | Layers | lyrs |
Geometric | Parts | prts |
Points | pnts | |
Utility | Strings | mostrs |
Database object | Prefix | Example |
---|---|---|
Container | con | conReports |
Database | db | dbAccounts |
DBEngine | dbe | dbeJet |
Document | doc | docSalesReport |
Field | fld | fldAddress |
Group | grp | grpFinance |
Index | idx | idxAge |
Parameter | prm | prmJobCode |
QueryDef | qry | qrySalesByRegion |
Recordset | rec | recForecast |
Relation | rel | relEmployeeDept |
TableDef | tdf | tdfCustomers |
User | usr | usrNew |
Workspace | wsp | wspMine |
Some examples:
Dim dbBiblio As Database
Dim recPubsInNY As Recordset, strSQLStmt As String
'Open database.
Set dbBiblio = OpenDatabase("BIBLIO.MDB")
' Set text for the SQL statement.
strSQLStmt = "SELECT * FROM Publishers WHERE " & _ State = 'NY'"
' Create the new Recordset object.
Set recPubsInNY = db.OpenRecordset(strSQLStmt, _ dbReadOnly)
Includes Class, Form, Code and User control Modules.
In general, the prefix for all instances of classes defined is the same as the class prefix, but with the initial capital in lower case. For example:
Dim dlgModelDefinition As DlgModelDefinition
Dim clsAnlaysisServerInterface As New ClsAnalysisServerInterface
An exception to this is the user control LabelLine, which is used widely as a general control, and is given all sorts of object names. Instead of the prefix uct, it has the prefix lal. For example:
Dim lalModelHeader As UctLabelLine
In addition to objects, constants and variables also require well-formed naming conventions. This section lists recommended conventions for constants and variables supported by Visual Basic. It also discusses the issues of identifying data type and scope.
Variables should always be defined with the smallest scope possible. Global (Public) variables can create enormously complex state machines and make the logic of an application extremely difficult to understand. Global variables also make the reuse and maintenance of the code much more difficult.
Variables in Visual Basic can have the following scope:
Scope | Declaration | Visible in |
---|---|---|
Procedure-level | Private in procedure, subroutine, or function | The procedure in which it is declared |
Module-level | Private in the declarations section of a form or code module (.frm, .bas) | Every procedure in the form or code module |
Global | Public in the declarations section of a code module (.bas) | Everywhere in the application |
In a Visual Basic application, global variables should be used only when there is no other convenient way to share data between forms. When global variables must be used, it is good practice to declare them all in a single module, grouped by function. Give the module a meaningful name that indicates its purpose e.g. modPublic.
It is good coding practice to write modular code whenever possible. For example, if the application displays a dialog box, put all the controls and code required to perform the dialog’s task in a single form. This helps to keep the application’s code organized into useful components and minimizes its run-time overhead.
With the exception of global variables (which should not be passed), procedures and functions should operate only on objects passed to them. Global variables that are used in procedures should be identified in the declaration section at the beginning of the procedure.
Declaring all variables saves programming time by reducing the number of bugs caused by typos (for example, aUserNameTmp vs. sUserNameTmp vs. sUserNameTemp).
Within Visual Basic, select Tools => Options… then, in the Editor tab, check the Require Variable Declaration option. This puts an Option Explicit statement at the beginning of each new form, which in turn requires that all variables in a Visual Basic program are declared explicitly.
Variables should be prefixed to indicate their data type. The prefix should also be extended to indicate the scope of the variable (see following section).
Use the following prefixes to indicate a variable’s data type.
Data type | Prefix | Example |
---|---|---|
Boolean | bln | blnFound |
Byte | byt | bytRasterData |
Collection object | col | colWidgets |
Currency | cur | curRevenue |
Date (Time) | dtm | dtmStart |
Double | dbl | dblTolerance |
Error | err | errOrderNum |
Integer | int | intQuantity |
Long | lng | lngDistance |
Object | obj | objCurrent |
Single | sng | sngAverage |
String | str | strFName |
User-defined type | udt | udtEmployee |
Variant | vnt | vntCheckSum |
The only exception to the above is for simple looping variables in For loops, which are always integers (see below).
As project size grows, so does the value of recognizing variable scope quickly. A one-letter scope prefix preceding the type prefix provides this, without greatly increasing the size of variable names.
Scope | Prefix | Example |
---|---|---|
Global | g | gstrUserName |
Module-level | m | mblnCalcInProgress |
Local to procedure | None | dblVelocity |
A variable has global scope if it is declared Public in a standard module or a form module. A variable has module-level scope if declared Private in a standard module or form module, respectively.
Note Consistency is crucial to the productive use of this technique - the syntax checker in Visual Basic will not catch module-level variables that begin with “p.”
The body of constant names should be all upper case. In addition, use the same prefix rules as for variables. For example:
mintUSER_LIST_MAX 'Max entry limit for User list
'(integer value,local to module)
gstrNEW_LINE 'New Line character
'(string, global to application)
These are all given the prefix dst (for Distance). For example:
Public Enum ProjectSettingsLocations
dstProject = 0
dstRegistry = 1
dstProjectThenRegistry = 2
End Enum
Enumerations should be used in place of constants wherever possible, as they then appear in the drop down list when you are typing, reducing typing errors.
In a large project with many user-defined types, it is often useful to give each such type a three-character prefix of its own. If these prefixes begin with “u” they will still be easy to recognize quickly when you are working with a user-defined type. For example, “ucli” could be used as the prefix for variables of a user-defined Client type.
The following is a list of user defined types:
Data type | Prefix | Example | Date added |
---|---|---|---|
none yet | none yet | none yet | none yet |
The body of a variable or procedure name should use mixed case and should be as long as necessary to describe its purpose. In addition, function names should begin with a verb, such as InitNameArray or CloseDialog.
For frequently used or long terms, standard abbreviations are recommended to help keep name lengths reasonable. In general, variable names greater than 32 characters can be difficult to read on VGA displays.
When using abbreviations, make sure they are consistent throughout the entire application. Randomly switching between Cnt and Count within a project will lead to unnecessary confusion.
When you use a new abbreviation, add it to the list below and write in the date.
The following is the current list of abbreviations:
Use | Abbreviation | Example | Date added |
---|---|---|---|
Looping variable (note - this is the only time no prefix is required) | i, j, k | i | 2/2/98 |
Use base 0 wherever possible, and put Option Base 0 at the beginning of all modules, so it is the default.
All forms and code modules should have the same basic structure:
Separate each of these sections with a dashed line
-----------------------------------------
See the Distance code for examples.
All procedures and functions should begin with a brief comment describing the purpose and functional characteristics of the procedure (what it does), unless it is extrememly obvious. This description should not describe the implementation details (how it does it) because these often change over time, resulting in unnecessary comment maintenance work, or worse yet, erroneous comments. The code itself and any necessary inline comments will describe the implementation. However, for procedures that implement complex algorithms or use tricky programming, some brief implementation notes can be useful, so long as they are clearly delimited from the rest of the text (see table below).
Arguments passed to a procedure should be described when their functions are not obvious and when the procedure expects the arguments to be in a specific range. Function return values and global variables that are changed by the procedure, especially through reference arguments, should also be described at the beginning of each procedure.
Procedure header comment blocks should include the following section headings as required. For examples, see the next section on Formatting Code.
Section heading | Comment description |
---|---|
Purpose | What the procedure does, but not how |
Called from | List of modules that call this module, only where this would be useful (mostly for non event driven utility procedures) |
or | |
Called when | For event procedures, where not obvious |
Assumptions | List of each external variable, control, open file, or other element that is not obvious |
Effects | List of each affected external variable, control, or file and the effect it has, only if this is not obvious |
Inputs | Each argument that may not be obvious. Arguments are on a separate line with inline comments. |
Returns | Explanation of the values returned by functions |
Implementation note | General notes about the algorithm used or other implementation details can be included if they will be useful to the understanding of the procedure |
Seperate these from the other comments by one blank line, so they can be easily identified and changed if the implementation changes. |
Remember the following points:
Because many programmers still use VGA displays, screen space should be conserved as much as possible while still allowing code formatting to reflect logic structure and nesting. Here are a few pointers:
Function intFindUser (strUserList() As String, strTargetUser As _
String)As Integer
'Purpose: Locates the first occurrence of a
' specified user in the UserList array.
'Inputs:
' strUserList(): the list of users to be searched.
' strTargetUser: the name of the user to search for.
'Returns: The index of the first occurrence of the
' rsTargetUser in the rasUserList array.
' If target user is not found, return -1.
Dim i As Integer ' counter.
Dim blnFound As Integer ' Target found flag.
intFindUser = -1
i = 0
Do While i <= Ubound(strUserList) and Not blnFound
If strUserList(i) = strTargetUser Then
blnFound = True
intFindUser = i
End If
Loop
End Function
Defined constants at the module level should be grouped by function and placed at the beginning of the module to which they refer. Modules used in more than one form should do in ModGlobal. Where there is any doubt, put it in ModGlobal!
Always use the & operator when linking strings and the + operator when working with numerical values. Using the + operator to concatenate may cause problems when operating on two variants. For example:
vntVar1 = "10.01"
vntVar2 = 11
vntResult = vntVar1 + vntVar2 'vntResult = 21.01
vntResult = vntVar1 & vntVar2 'vntResult = 10.0111
When creating a long string, use the underscore line-continuation character to create multiple lines of code so that you can read or debug the string easily. This technique is particularly useful when displaying a message box (MsgBox) or input box (InputBox) or when creating an SQL string. For example:
Dim Msg As String
Msg = "This is a paragraph that will be " _
& "in a message box. The text is" _
& " broken into several lines of code" _
& " in the source code, making it easier" _
& " for the programmer to read and debug."
MsgBox Msg
Dim strQuery As String
strQuery = "SELECT *" _
& " FROM Titles" _
& " WHERE [Year Published] > 1988"
TitlesQry.SQL = strQuery
The filename should be the same as the form or module name, minus the prefix. The file extension is the standard .frm for Forms, .mod for Modules, .cls for Classes and .ctl for User Controls. Examples:
Form/module name | Filename |
---|---|
CDlgAddData | AddData.dlg |
CModDatabase | Database.mod |