It is a good idea to establish naming conventions for your Visual Basiccode. This article gives you the naming conventions used by MicrosoftConsulting Services (MCS).
This document is a superset of the Visual Basic coding conventions found inthe Visual Basic "Programmer's Guide."
NOTE: The third-party controls mentioned in this article are manufacturedby vendors independent of Microsoft. Microsoft makes no warranty, impliedor otherwise, regarding these controls' performance or reliability.
Naming conventions help Visual Basic programmers:
- standardize the structure, coding style and logic of an application.
- create precise, readable, and unambiguous source code.
- be consistent with other language conventions (most importantly, the Visual Basic Programmers Guide and standard Windows C Hungarian notation).
- be efficient from a string size and labor standpoint, thus allowing a greater opportunity for longer and fuller object names.
- define the minimal requirements necessary to do the above.
Setting Environment Options
Use Option Explicit. Declare all variables to save programming time byreducing the number of bugs caused by typos (for example, aUserNameTmp vs.sUserNameTmp vs. sUserNameTemp). In the Environment Options dialog, setRequire Variable Declaration to Yes. The Option Explicit statement requiresyou to declare all the variables in your Visual Basic program.Save Files as ASCII Text. Save form (.FRM) and module (.BAS) files as ASCIItext to facilitate the use of version control systems and minimize thedamage that can be caused by disk corruption. In addition, you can:
- use your own editor
- use automated tools, such as grep
- create code generation or CASE tools for Visual Basic
- perform external analysis of your Visual Basic code
To have Visual Basic always save files as ASCII text, from the EnvironmentOptions dialog, set the Default Save As Format option to Text.
Object Naming Conventions for Standard Objects
The following tables define the MCS standard object name prefixes. Theseprefixes are consistent with those documented in the Visual BasicProgrammers Guide.
Prefix Object Type Example-------------------------------------------------------ani Animation button aniMailBoxbed Pen Bedit bedFirstNamecbo Combo box and drop down list box cboEnglishchk Checkbox chkReadOnlyclp Picture clip clpToolbarcmd (3d) Command button (3D) cmdOk (cmd3dOk)com Communications comFaxctr Control (when specific type unknown) ctrCurrentdat Data control datBibliodir Directory list box dirSourcedlg Common dialog control dlgFileOpendrv Drive list box drvTargetfil File list box filSourcefrm Form frmEntryfra (3d) Frame (3d) fraStyle (fra3dStyle)gau Gauge gauStatusgpb Group push button gpbChannelgra Graph graRevenuegrd Grid grdPriceshed Pen Hedit hedSignaturehsb Horizontal scroll bar hsbVolumeimg Image imgIconink Pen Ink inkMapkey Keyboard key status keyCapslbl Label lblHelpMessagelin Line linVerticallst List box lstPolicyCodesmdi MDI child form mdiNotempm MAPI message mpmSentMessagemps MAPI session mpsSessionmci MCI mciVideomnu Menu mnuFileOpenopt (3d) Option Button (3d) optRed (opt3dRed)ole OLE control oleWorksheetout Outline control outOrgChartpic Picture picVGApnl3d 3d Panel pnl3drpt Report control rptQtr1Earningsshp Shape controls shpCirclespn Spin control spnPagestxt Text Box txtLastNametmr Timer tmrAlarmvsb Vertical scroll bar vsbRate
Object Naming Convention for Database Objects
Prefix Object Type Example------------------------------------------db ODBC Database dbAccountsds ODBC Dynaset object dsSalesByRegionfdc Field collection fdcCustomerfd Field object fdAddressix Index object ixAgeixc Index collection ixcNewAgeqd QueryDef object qdSalesByRegionqry (suffix) Query (see NOTE) SalesByRegionQryss Snapshot object ssForecasttb Table object tbCustomertd TableDef object tdCustomers
NOTE: Using a suffix for queries allows each query to be sorted with itsassociated table in Microsoft Access dialogs (Add Table, List TablesSnapshot).
Menu Naming Conventions
Applications frequently use an abundance of menu controls. As a result, youneed a different set of naming conventions for these controls. Menu controlprefixes should be extended beyond the initial mnu label by adding anadditional prefix for each level of nesting, with the final menu caption atthe end of the name string. For example:
Menu Caption Sequence Menu Handler NameHelp.Contents mnuHelpContentsFile.Open mnuFileOpenFormat.Character mnuFormatCharacterFile.Send.Fax mnuFileSendFaxFile.Send.Email mnuFileSendEmail
When this convention is used, all members of a particular menu group arelisted next to each other in the object drop-down list boxes (in the codewindow and property window). In addition, the menu control names clearlydocument the menu items to which they are attached.
Naming Conventions for Other Controls
For new controls not listed above, try to come up with a unique threecharacter prefix. However, it is more important to be clear than to stickto three characters.
For derivative controls, such as an enhanced list box, extend the prefixesabove so that there is no confusion over which control is really beingused. A lower-case abbreviation for the manufacturer would also typicallybe added to the prefix. For example, a control instance created from theVisual Basic Professional 3D frame could uses a prefix of fra3d to avoidconfusion over which control is really being used. A command button fromMicroHelp could use cmdm to differentiate it from the standard commandbutton (cmd).
Each third-party control used in an application should be listed in theapplication's overview comment section, providing the prefix used for thecontrol, the full name of the control, and the name of the software vendor:
Prefix Control Type Vendorcmdm Command Button MicroHelp
Variable and Routine Naming
Variable and function names have the following structure:<prefix><body><qualifier><suffix>
Part Description Example--------------------------------------------------------------------------<prefix> Describes the use and scope of the variable. iGetRecordNext<body> Describes the variable. iGetNameFirst<qualifier> Denotes a derivative of the variable. iGetNameLast<suffix> The optional Visual Basic type character. iGetRecordNext%
The following tables define variable and function name prefixes that arebased on Hungarian C notation for Windows. These prefixes should be usedwith all variables and function names. Use of old Basic suffixes (such as%, &, #, etc.) are discouraged.
Variable and Function Name Prefixes:
Prefix Converged Variable Use Data Type Suffix--------------------------------------------------------------------------b bln Boolean Integer %c cur Currency - 64 bits Currency @d dbl Double - 64 bit Double # signed quantitydt dat Date and Time Variante err Errorf sng Float/Single - 32 Single ! bit signed floating pointh Handle Integer %i Index Integer %l lng Long - 32 bit Long & signed quantityn int Number/Counter Integer %s str String String $u Unsigned - 16 bit Long & unsigned quantity udt User-defined typevnt vnt Variant Varianta Array
NOTE: the values in the Converged column represent efforts to pull togetherthe naming standards for Visual Basic, Visual Basic for Applications, andAccess Basic. It is likely that these prefixes will become Microsoftstandards at some point in the near future.
Scope and Usage Prefixes:
Prefix Descriptiong Globalm Local to module or formst Static variable(no prefix) Non-static variable, prefix local to procedurev Variable passed by value (local to a routine)r Variable passed by reference (local to a routine)
Hungarian notation is as valuable in Visual Basic as it is in C. Althoughthe Visual Basic type suffixes do indicate a variable's data type, they donot explain what a variable or function is used for, or how it can beaccessed. Here are some examples:
iSend - Represents a count of the number of messages sent
bSend - A Boolean flag defining the success of the last Send operation
hSend - A Handle to the Comm interface
Each of these variable names tell a programmer something very different.This information is lost when the variable name is reduced to Send%. Scopeprefixes such as g and m also help reduce the problem of name contentionespecially in multi-developer projects.
Hungarian notation is also widely used by Windows C programmers andconstantly referenced in Microsoft product documentation and in industryprogramming books. Additionally, the bond between C programmers andprogrammers who use Visual Basic will become much stronger as the VisualC++ development system gains momentum. This transition will result in manyVisual Basic programmers moving to C for the first time and manyprogrammers moving frequently back and forth between both environments.
The Body of Variable and Routine Names
The body of a variable or routine name should use mixed case and should beas long as necessary to describe its purpose. In addition, function namesshould begin with a verb, such as InitNameArray or CloseDialog.
For frequently used or long terms, standard abbreviations are recommendedto help keep name lengths reasonable. In general, variable names greaterthan 32 characters can be difficult to read on VGA displays.
When using abbreviations, make sure they are consistent throughout theentire application. Randomly switching between Cnt and Count within aproject will lead to unnecessary confusion.
Qualifiers on Variable and Routine Names
Related variables and routines are often used to manage and manipulate acommon object. In these cases, use standard qualifiers to label thederivative variables and routines. Although putting the qualifier after thebody of the name might seem a little awkward (as in sGetNameFirst,sGetNameLast instead of sGetFirstName, sGetLastName), this practice willhelp order these names together in the Visual Basic editor routine lists,making the logic and structure of the application easier to understand.The following table defines common qualifiers and their standard meaning:
Qualifier Description (follows Body)--------------------------------------------------------------------------First First element of a set.Last Last element of a set.Next Next element in a set.Prev Previous element in a set.Cur Current element in a set.Min Minimum value in a set.Max Maximum value in a set.Save Used to preserve another variable that must be reset later.Tmp A "scratch" variable whose scope is highly localized within the code. The value of a Tmp variable is usually only valid across a set of contiguous statements within a single procedure.Src Source. Frequently used in comparison and transfer routines.Dst Destination. Often used in conjunction with Source.
User Defined Types
Declare user defined types in all caps with _TYPE appended to the end ofthe symbol name. For example:
Type CUSTOMER_TYPE sName As String sState As String * 2 lID as Long End Type
When declaring an instance variable of a user defined type, add a prefix tothe variable name to reference the type. For example:
Dim custNew as CUSTOMER_TYPE
The body of constant names should be UPPER_CASE with underscores (_)between words. Although standard Visual Basic constants do not includeHungarian information, prefixes like i, s, g, and m can be very useful inunderstanding the value and scope of a constant. For constant names, followthe same rules as variables. For Example:
<mnUSER_LIST_MAX ' Max entry limit for User list (integer value, ' local to module) gsNEW_LINE ' New Line character string (global to entire ' application)
Variant Data Type
If you know that a variable will always store data of a particular type,Visual Basic can handle that data more efficiently if you declare avariable of that type.
However, the variant data type can be extremely useful when working withdatabases, messages, DDE, or OLE. Many databases allow NULL as a validvalue for a field. Your code needs to distinguish between NULL, 0 (zero),and "" (empty string). Many times, these types of operations can use ageneric service routine that does not need to know the type of data itreceives to process or pass on the data. For example:
Sub ConvertNulls(rvntOrg As Variant, rvntSub As Variant) ' If rvntOrg = Null, replace the Null with rvntSub If IsNull(rvntOrg) Then rvntOrg = rvntSub End Sub
The are some drawbacks, however, to using variants. Code statements thatuse variants can sometimes be ambiguous to the programmer. For example:
vnt1 = "10.01" : vnt2 = 11 : vnt3 = "11" : vnt4 = "x4" vntResult = vnt1 + vnt2 ' Does vntResult = 21.01 or 10.0111? vntResult = vnt2 + vnt1 ' Does vntResult = 21.01 or 1110.01? vntResult = vnt1 + vnt3 ' Does vntResult = 21.01 or 10.0111? vntResult = vnt3 + vnt1 ' Does vntResult = 21.01 or 1110.01? vntResult = vnt2 + vnt4 ' Does vntResult = 11x4 or ERROR? vntResult = vnt3 + vnt4 ' Does vntResult = 11x4 or ERROR?
The above examples would be much less ambiguous and easier to read, debug,and maintain if the Visual Basic type conversion routines were usedinstead. For Example:
iVar1 = 5 + val(sVar2) ' use this (explicit conversion) vntVar1 = 5 + vntVar2 ' not this (implicit conversion)
Commenting Your Code
All procedures and functions should begin with a brief comment describingthe functional characteristics of the routine (what it does). Thisdescription should not describe the implementation details (how it does it)because these often change over time, resulting in unnecessary commentmaintenance work, or worse yet, erroneous comments. The code itself and anynecessary in-line or local comments will describe the implementation.
Parameters passed to a routine should be described when their functions arenot obvious and when the routine expects the parameters to be in a specificrange. Function return values and global variables that are changed by theroutine (especially through reference parameters) must also be described atthe beginning of each routine.
Routine header comment blocks should look like this (see the next section"Formatting Your Code" for an example):
Section Comment Description--------------------------------------------------------------------------Purpose What the routine does (not how).Inputs Each non-obvious parameter on a separate line with in-line commentsAssumes List of each non-obvious external variable, control, open file, and so on.Returns Explanation of value returned for functions.Effects List of each effected external variable, control, file, and so on and the affect it has (only if this is not obvious)
Every non-trivial variable declaration should include an in-line commentdescribing the use of the variable being declared.
Variables, controls, and routines should be named clearly enough that in-line commenting is only needed for complex or non-intuitive implementationdetails.
An overview description of the application, enumerating primary dataobjects, routines, algorithms, dialogs, database and file systemdependencies, and so on should be included at the start of the .BAS modulethat contains the project's Visual Basic generic constant declarations.
NOTE: The Project window inherently describes the list of files in aproject, so this overview section only needs to provide information on themost important files and modules, or the files the Project window doesn'tlist, such as initialization (.INI) or database files.
Formatting Your Code
Because many programmers still use VGA displays, screen real estate must beconserved as much as possible, while still allowing code formatting toreflect logic structure and nesting.
Standard, tab-based, block nesting indentations should be two to fourspaces. More than four spaces is unnecessary and can cause statements to behidden or accidentally truncated. Less than two spaces does notsufficiently show logic nesting. In the Microsoft Knowledge Base, we use athree-space indent. Use the Environment Options dialog to set the defaulttab width.
The functional overview comment of a routine should be indented one space.The highest level statements that follow the overview comment should beindented one tab, with each nested block indented an additional tab. Forexample:
**************************************************************************'Purpose: Locate first occurrence of a specified user in UserList array.'Inputs: rasUserList(): the list of users to be searched' rsTargetUser: 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 not found, return -1.'**************************************************************************'VB3Line: Enter the following lines as one lineFunction iFindUser (rasUserList() As String, rsTargetUser as String) _ As Integer Dim i As Integer ' loop counter Dim bFound As Integer ' target found flag iFindUser = -1 i = 0 While i <= Ubound(rasUserList) and Not bFound If rasUserList(i) = rsTargetUser Then bFound = True iFindUser = i End If WendEnd Function
Variables and non-generic constants should be grouped by function ratherthan by being split off into isolated areas or special files. Visual Basicgeneric constants such as HOURGLASS should be grouped in a single module(VB_STD.BAS) to keep them separate from application-specific declarations.
Always use an ampersand (&) when concatenating strings, and use the plussign (+) when working with numerical values. Using a plus sign (+) withnon-numerical values, 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
Variables should always be defined with the smallest scope possible.Global variables can create enormously complex state machines and make thelogic of an application extremely difficult to understand. Global variablesalso make the reuse and maintenance of your code much more difficult.Variables in Visual Basic can have the following scope:
Scope Variable Declared In: Visibility--------------------------------------------------------------------------Procedure-level Event procedure, sub, or Visible in the function procedure in which it is declaredForm-level, Declarations section of a form Visible in everyModule-level or code module (.FRM, .BAS) procedure in the form or code moduleGlobal Declarations section of a code Always visible module (.BAS, using Global keyword)
In a Visual Basic application, only use global variables when there is noother convenient way to share data between forms. You may want to considerstoring information in a control's Tag property, which can be accessedglobally using the form.object.property syntax.
If you must use global variables, it is good practice to declare all ofthem in a single module and group them by function. Give the module ameaningful name that indicates its purpose, such as GLOBAL.BAS.
With the exception of global variables (which should not be passed),procedures and functions should only operate on objects that are passed tothem. Global variables that are used in routines should be identified inthe general comment area at the beginning of the routine. In addition, passarguments to subs and functions using ByVal, unless you explicitly want tochange the value of the passed argument.
Write modular code whenever possible. For example, if your applicationdisplays a dialog box, put all the controls and code required to performthe dialog's task in a single form. This helps to keep the application'scode organized into useful components and minimizes its runtime overhead.
NOTE: The products discussed below are manufactured by vendors independentof Microsoft. Microsoft makes no warranty, implied or otherwise, regardingthese products' performance or reliability.
The following table lists standard third-party vendor name prefixcharacters to be used with control prefixes:
Vendor Abbv-------------------------MicroHelp (VBTools) mPioneer Software pCrescent Software cSheridan Software sOther (Misc) o
The following table lists standard third-party control prefixes:
Control Control Abbr Vendor Example VBX FileType Name Name--------------------------------------------------------------------------Alarm Alarm almm MicroHelp almmAlarm MHTI200.VBXAnimate Animate anim MicroHelp animAnimate MHTI200.VBXCallback Callback calm MicroHelp calmCallback MHAD200.VBXCombo Box DB_Combo cbop Pioneer cbopComboBox QEVBDBF.VBXCombo Box SSCombo cbos Sheridan cbosComboBox SS3D2.VBXCheck Box DB_Check chkp Pioneer chkpCheckBox QEVBDBF.VBXChart Chart chtm MicroHelp chtmChart MHGR200.VBXClock Clock clkm MicroHelp clkmClock MHTI200.VBXButton Command cmdm MicroHelp cmdmCommandButton MHEN200.VBX ButtonButton DB_Command cmdp Pioneer cmdpCommandButton QEVBDBF.VBXButton (Group) Command cmgm MicroHelp cmgmBtton MHGR200.VBX Button (multiple)Button Command cmim MicroHelp cmimCommandButton MHEN200.VBX Button (icon)CardDeck CardDeck crdm MicroHelp crdmCard MHGR200.VBXDice Dice dicm MicroHelp dicmDice MHGR200.VBXList Box (Dir) SSDir dirs Sheridan dirsDirList SS3D2.VBXList Box (Drv) SSDrive drvs Sheridan drvsDriveList SS3D2.VBXList Box (File) File List film MicroHelp filmFileList MHEN200.VBXList Box (File) SSFile fils Sheridan filsFileList SS3D2.VBXFlip Flip flpm MicroHelp flpmButton MHEN200.VBXScroll Bar Form Scroll fsrm MicroHelp fsrmFormScroll ???Gauge Gauge gagm MicroHelp gagmGauge MHGR200.VBXGraph Graph gpho Other gphoGraph XYGRAPH.VBXGrid Q_Grid grdp Pioneer grdpGrid QEVBDBF.VBXScroll Bar Horizontal hsbm MicroHelp hsbmScroll MHEN200.VBX Scroll BarScroll Bar DB_HScroll hsbp Pioneer hsbpScroll QEVBDBF.VBXGraph Histo hstm MicroHelp hstmHistograph MHGR200.VBXInvisible Invisible invm MicroHelp invmInvisible MHGR200.VBXList Box Icon Tag itgm MicroHelp itgmListBox MHAD200.VBXKey State Key State kstm MicroHelp kstmKeyState MHTI200.VBXLabel Label (3d) lblm MicroHelp lblmLabel MHEN200.VBXLine Line linm MicroHelp linmLine MHGR200.VBXList Box DB_List lstp Pioneer lstpListBox QEVBDBF.VBXList Box SSList lsts Sheridan lstsListBox SS3D2.VBXMDI Child MDI Control mdcm MicroHelp mdcmMDIChild ???Menu SSMenu mnus Sheridan mnusMenu SS3D3.VBXMarque Marque mrqm MicroHelp mrqmMarque MHTI200.VBPicture OddPic odpm MicroHelp odpmPicture MHGR200.VBXPicture Picture picm MicroHelp picmPicture MHGR200.VBXPicture DB_Picture picp Pioneer picpPicture QEVBDBF.VBXProperty Vwr Property pvrm MicroHelp pvrmPropertyViewer MHPR200.VBX ViewerOption (Group) DB_RadioGroup radp Pioneer radqRadioGroup QEVBDBF.VBXSlider Slider sldm MicroHelp sldmSlider MHGR200.VBXButton (Spin) Spinner spnm MicroHelp spnmSpinner MHEN200.VBXSpreadsheet Spreadsheet sprm MicroHelp sprmSpreadsheet MHAD200.VBXPicture Stretcher strm MicroHelp strmStretcher MHAD200.VBXScreen Saver Screen Saver svrm MicroHelp svrmSaver MHTI200.VBXSwitcher Switcher swtm MicroHelp swtmSwitcher ???List Box Tag tagm MicroHelp tagmListBox MHEN200.VBXTimer Timer tmrm MicroHelp tmrmTimer MHTI200.VBXToolBar ToolBar tolm MicroHelp tolmToolBar MHAD200.VBXList Box Tree trem MicroHelp tremTree MHEN200.VBXInput Box Input (Text) txtm MicroHelp inpmText MHEN200.VBXInput Box DB_Text txtp Pioneer txtpText QEVBDBF.VBXScroll Bar Vertical vsbm MicroHelp vsbmScroll MHEN200.VBX Scroll BarScroll Bar DB_VScroll vsbp Pioneer vsbpScroll QEVBDBF.VBX