The use of declaration standards in Visual Basic includes both the naming of code and user interface elements (nomenclature), and the declaration and use of those elements (instantiation). This discussion of declaration begins with the nomenclature standards. Believe it or not, most elements defined within Visual Basic do not use the Hungarian standards you have heard so much about. Each of the elements described in this chapter takes its naming standards from a combination of tradition and functionality.
The names given to variables within a Visual Basic application are one of the most obvious forms of declaration standards in your program. Hungarian naming conventions provide a method by which the name given to a variable can carry information about the type, scope, and usage of a variable. Invented by Charles Simonyi of Microsoft (a Hungarian by descent), this system of naming variables was first used for applications written in the C language. Perhaps Hungarian is an appropriate moniker for the system since, like many human languages, the convention comes in a variety of dialects. The dialect presented here is a distillation of several variations, with adequate room left for the addition of new entries.
A variable name is Hungarian if it is built up from four components.
[scope][tag]basename[qualifier]
Scope indicates the visibility of the variable within the application. The scope, when present, is the first component of a Hungarian variable name, and it always appears in lower case. Table 9.1 identifies the different values for the scope.
Scope | Description |
---|---|
g | A global variable, defined within the Declarations section of a module using the Public keyword. Variables of this scope are accessible from all routines within the application. |
m | A module-level variable, defined within the Declarations section of the module using the Private keyword. Variables of this scope are accessible from all routines within the module, class, form, or other code file in which the variable is declared, but are hidden from other modules. |
x | A local variable, defined with the Static keyword. |
nothing | A local variable, defined with the Dim keyword. Variables passed into a routine through its argument list also have no scope prefix. Also, user interface control names do not require the use of a scope prefix, as they are module-level in scope by definition. |
Most variables defined within a Sub, Function, or Property routine will have no scope prefix; only those local variables declared with the Static keyword need indicate the scope. All variables defined outside of a Sub, Function, or Property routine will always start with a "g" or "m" prefix. (See the "Nomenclature Exceptions" section for an exception with public class variables.)
VBScript programmers should note that all variables defined outside the confines of a Sub or Function are actually module-level in scope. However, because of the temporary nature of Visual Basic script code, concepts like "module-level" and "global-level" are not always relevant. When declaring variables in VBScript outside of a defined routine, either use the local variable declaration syntax with the Dim statement, or the module-level syntax with the Private statement (prefixing variables with "m"). Whichever method you choose, be consistent throughout your script code. All examples of VBScript declarations in this book use the Private syntax with "m" prefixes.
Private mnCounter
Tag is used to identify the type of a variable being declared. In general, tag values range from one to four characters in length, and are always lower case.
If you are declaring an array variable, the letter "a" is prefixed to the tag. For example, the declaration
Dim asColonies(1 To 13) As String
indicates a local array of 13 string variables, while
Dim sColony As String
declares storage for a single local string value. The "a" array indicator, when present, always appears before the actual tag, but after any scope prefix.
Table 9.2 presents a list of the more common tag values used in Visual Basic programming.
Tag | Meaning |
---|---|
b | Boolean data type. In Visual Basic 3.0, Boolean values were declared as Integer. Visual Basic 4.0 introduced a true Boolean data type. |
by | Byte data type. |
ctr | Generic control type, when a control variable can indicate more than one type of control. |
dt | Date data type for handling dates or times. |
fc | Currency data type. |
fd | Double data type. |
fs | Single data type. |
h | Handle data type. In Visual Basic 3.0, handles were declared as Integer. Beginning with the 32-bit version of Visual Basic 4.0, handles are declared as Long. |
l | Long data type (the tag is the letter ell). |
n | Integer data type. |
obj | Object data type. |
s | String data type. For fixed-length strings, append the size of the string to the end of the variable name, as in sBuffer200. |
va | Variant data type used for Variant Arrays. |
vnt | Variant data type. In general, Variants should not be used unless no other data type will meet a particular need. |
Because of the unlimited number of ActiveX components that can be added or created for use with Visual Basic, a full rendering of tags is impossible. From time to time you will have to add to the lists of tags found in this chapter. When adding new tags to the list, take care not to create conflicts with other prefix combinations. For example, if you create an ActiveX component for a chemistry application that represents a gas, do not use the tag "gas" for your new object. A declaration such as
Dim gasHelium As ChemGas
could be interpreted as a global array of string variables ("g" for global, "a" for array, "s" for string, although the declaration shows that this is truly not the case). Select a unique tag, ranging from two to five characters, that will be free from such conflicts of interpretation.
Basename is a traditional variable name, such as "CustomerName" or "ScanPosition," always in mixed case with an initial capital letter. Qualifier is an extension that differentiates variations in related variables. For example, lCustOrderFirst and lCustOrderLast indicate the first and last orders for a customer. The qualifiers for these variables are "First" and "Last." For the purposes of the standards described in this chapter, you can consider Qualifier to be part of Basename. When declaring variables, the combined Basename and Qualifier must be at least two characters in length.
Visual Basic, Scripting Edition, contains only a single non-object data type: Variant. It would be somewhat useless to prefix every variable in your VBScript page with the "vnt" tag, since such naming would not distinguish between the different uses of these Variants. When declaring variables in VBScript, provide names that you would give the same variables in a standard Visual Basic application. For instance, if you declare a variable that will only be used to hold a customer name, name it "sCustName" instead of "vntCustName."
Avoid negative variable names; that is, variable names containing the words "No," "Not," and other similar words, especially when using Boolean variables. It is clearer to write
If bReady Then
rather than
If Not(bNotReady) Then
Constants are non-variable variables; that is, a named value that cannot be changed while the application is running. They include those programmer-defined elements created with either the Const or #Const keywords. You can also establish a constant by entering it in the Conditional Compilation Arguments field in the Visual Basic Project Properties form.
A constant name always appears with upper-case letters and digits, with underscore characters separating the significant words of the name.
Public Const SLICE_OF_PI = 3.1416#
Use a common prefix for related constants, not a suffix.
Correct
Private Const TAB_CUSTOMER = 1 Private Const TAB_VENDOR = 2 Private Const TAB_ORDER = 3
Incorrect
Private Const CUSTOMER_TAB = 1 Private Const VENDOR_TAB = 2 Private Const ORDER_TAB = 3
If you are adding constants to your project that were defined by a third party (such as those found in the API Text Viewer application supplied with Visual Basic), retain the case and style used by the original vendor.
User-defined types are created by using the Type statement. The syntax of the statement includes two namable parts, the initial tag, and the variable elements that make up the data type.
Private Type CustomerType ' This is the tag line lCustomerID As Long ' This is an element line sCustomerName As String ' This is another element End Type
When naming the elements within the data type definition, follow the Hungarian naming standards for local variables listed earlier in this chapter. The data type tag ("CustomerType" in this example) appears in mixed-case text, beginning with a capital letter, and with no underscore characters. It should be short, yet descriptive. Always end the tag name with the word "Type."
You can create enumerated lists of long integer values through the Enum statement. Like the syntax for user-defined types, the syntax of enumerated data types has two parts: an introductory tag, and a list of elements.
Public Enum CompassPointEnum ' The tag line pntNorth = 1 ' And four element lines pntEast pntSouth pntWest End Enum
The tag name of the data type appears in mixed-case text, with an initial capital letter, and no underscore characters. It should state clearly the purpose of the data type, although it need not be overly wordy. Always follow the tag name with the text "Enum" as shown in the "CompassPointEnum" tag name in the example.
The elements within the data type look a lot like Hungarian variable names. They are not true Hungarian names because the initial text does not identify the data type of each element (which is Long). Each element should begin with a lower-case leader, with the same leader applied to each element within the data type ("pnt" in this example). This leader is a two-to-five letter abbreviation for the type of elements being enumerated (compass "point" in the example). Follow the leader with a unique mixed-case element name. Avoiding conflicts with Hungarian variable prefixes is a good idea, but if the context of the enumerated constant set is clear, it is permissible to share prefixes with a seldom-used Hungarian prefix.
Line labels are used as destinations for GoTo, GoSub, and On Error GoTo statements. Visual Basic allows both numeric and alphanumeric line labels, but they are treated a little differently. Alphanumeric labels must be followed by a colon (":"), while the colon is optional after a numeric label. Numeric labels can be used as reference points in error processing (via the Erl keyword), while alphanumeric labels give no such information.
Although numeric labels seem to have the advantage, they should not be used within your application. Numeric line labels are a holdover from the original versions of the BASIC language, in which every line had to start with a line number. Only use numeric labels if you need to gather additional error information with the Erl keyword. Instead of meaningless numeric labels, use alphanumeric labels with names that hint at the purpose of the label. Line labels should consist of letters and digits only, starting with an initial capital letter, and containing no underscore characters. They appear in mixed case.
NextIteration: ' ----- Continue with the next group
Procedures include private and public functions, subroutines, properties (Get, Let, and Set), class methods, and other similar constructs. Unlike variables, procedures do not follow the Hungarian naming standards. Instead, all procedure names appear in mixed-case type, with each significant word capitalized. Never use underscores within the procedure name.
Public Sub DoAUsefulAction(nMethod As Integer)
Events, although true procedures, do not follow the naming system described in this section since the control or class on which the event is based defines the name of the event.
Private Sub txtBirthdate_GotFocus()
Because procedure names, especially those belonging to Function and Property Get procedures, do not contain any data type information, it is imperative that you supply meaningful names to all of your procedures.
If you have two private procedures in different modules that perform basically the same function (but they cannot be logically combined into a single public procedure), provide the same name for both procedures. For example, when I create a form that provides a basic "properties" view of a logical object (such as "customer properties" or "document properties"), I generally have these three procedures defined within the form's code pane.
Private Sub LoadData() ' ----- Populate the form with data from the active ' record. The module-level variable mlActiveID ' contains the primary key of the active record. Private Function VerifyData() As Boolean ' ----- Called when the user clicks the OK button. ' Make sure all fields contain valid data. ' Return True if all data is valid, or False if ' there are any problems. Private Function SaveData() As Boolean ' ----- Update the existing record, or add a new record ' to the database. Set mlActiveID to the ID of ' the new record. Return True on success.
I often have several of these properties forms within an application, and each form contains variations of these procedures, all with the names listed in this sample code. If you do reuse procedure names in this fashion, make sure that the procedures are always defined as Private to the module.
Avoid using negative names for your procedures. That is, refrain from words such as "Not" and "No" in the name of each procedure, especially those Function procedures that return a Boolean value. There is nothing more disarming than trying to decipher the return value of a negative function call.
If (Not ClearanceNotNeeded(sUser, bNotReady)) Then
The Declare statement is used to access dynamic link library (DLL) procedures supplied by Microsoft, another third party, or a member of your programming team. Once declared, such API procedures act as if they were written within the Visual Basic source code itself. Because of this, the naming conventions for Declare statements closely follow those of procedures. The Declare statement has an Alias option through which you can supply the original name of the procedure as it appears in the DLL. This is useful when the procedure name conflicts with a Visual Basic keyword or other code object. It is also useful for turning procedure names that do not follow the standards of this book into compliant procedures.
Public Declare Sub DoSomeWork Lib "makework.dll" _ Alias "do_some_work" (ByVal nWorkType As Integer)
In this example, the makework.dll library contains a subroutine named "do_some_work." Through the syntax of the Declare statement, the name was moved into the more compliant form "DoSomeWork."
Because the Declare statement accesses features that are external to the Visual Basic application, you may wish to bend the nomenclature rules in favor of overall project consistency. If you are developing your Visual Basic application in conjunction with another group using C++ or Pascal to create a DLL, using the naming conventions of the DLL routines when accessing those functions may simplify code reviews and other activities that involve both groups of programmers.
The user interface in the Visual Basic development environment consists of two types of objects: work areas (forms, user control backgrounds, Report Designer backgrounds, etc.), and controls to be placed on the work areas (menus, command buttons, text fields, combo boxes, etc.). All of these components fall under the same naming standards as variables: the Hungarian naming standards. These conventions apply both to actual user interface elements, and to references to such objects within the source code of your application. In fact, within the source code, user interface elements are really just instances of object (or class) variables, so they follow all of the Hungarian standards for variables. Within the user interface itself, Hungarian names are used without the scope prefix. User interface elements are module-level in scope by definition, so the scope prefix is redundant.
Tables 9.3 through 9.8 present various lists of Hungarian prefixes for user interface and other data object elements commonly used within Visual Basic. This list is by no means complete, as there are new user interface elements created by Microsoft and other vendors every day. When you employ additional third-party controls, append your standard names for those new elements to these lists to assure consistency in naming all of your user interface elements.
The first table in this set is Table 9.3, listing the standard Hungarian names for those controls built in to the Visual Basic form designer.
Tag | Meaning |
---|---|
cbo | ComboBox control, including the drop-down combo, simple combo, and drop-down list styles. |
chk | CheckBox control. |
cmd | CommandButton control |
dir | DirListBox control. See also "drv" and "fil." |
drv | DriveListBox control. See also "dir" and "fil." |
fil | FileListBox control. See also "dir" and "drv." |
fra | Frame control. |
hsb | HScrollBar (horizontal scroll bar) control. See also "vsb." |
lbl | Static Label control. |
lin | Line drawing object. See also "shp." |
lst | ListBox control, both standard and checkbox styles. |
mnu | Menu control, including standard, pop-up, and system menus. |
ole | OLE container control. If possible, include a short abbreviation of the foreign application in the control name. |
opt | OptionButton control. |
pic | PictureBox control. |
shp | Shape drawing object, including Rectangles, Squares, Ovals, Circles, Rounded Rectangles, and Rounded Squares. See also "lin." |
tmr | Timer control. |
txt | TextBox control, both single-line and multi-line styles. |
vsb | VScrollBar (vertical scroll bar) control. See also "hsb." |
Table 9.4 documents the Hungarian prefixes for user interface backgrounds and workspaces, those areas on which you place other controls. Also listed are naming conventions for code-only modules.
Tag | Meaning |
---|---|
bas | Standard code modules, which generally have a ".bas" extension. |
cls | Class modules. Do not use for variables of a generic class type. |
ctl | User control module. |
de | Data environment. |
dob | User document module. |
frm | Form module, both Single Document Interface (SDI) and Multi Document Interface (MDI) styles. |
htm | DHTML pages, documents, document titles, and document bodies. |
pag | Property page module. |
rpt | Data report module. |
wc | WebClass module. |
Included in Table 9.5 are those elements available in the DHTML Page Designer. Many of the elements in this table use the same prefixes as those for standard Visual Basic form controls.
Tag | Meaning |
---|---|
cbo | DHTML Select control. |
chk | DHTML CheckBox control. |
cmd | DHTML Button control, ResetButton control, and SubmitButton control. |
hdn | DHTML HiddenField control. |
htm | DHTML pages, documents, document titles, and document bodies. |
lin | DHTML HorizontalRule object. |
lnk | DHTML Hyperlink object. |
lst | DHTML List control. |
opt | DHTML Option control. |
p | DHTML paragraph ID. |
pic | DHTML Image control. |
tbl | DHTML tables and table bodies. |
td | DHTML table cells. |
tr | DHTML table rows. |
txt | DHTML TextField control, TextArea control, and PasswordField control. |
upl | DHTML FileUpload control. |
Table 9.6 contains Hungarian prefixes for data-related objects used in writing Visual Basic data access code with any of the standard data interfaces (DAO, RDO, ADO, etc.).
Tag | Meaning |
---|---|
clm | RDO column object or collection. |
com | ADO command object. Also for command objects within a data environment. |
con | ADO connection object, DAO connection object or collection, or RDO connection object or collection. Also for connection objects within a data environment. |
ctn | DAO container object or collection. |
db | DAO database object or collection. |
dbe | DAO database engine object, or RDO database engine object. |
doc | DAO document object or collection. |
dta | Intrinsic Data control, ADO Data control, or Remote Data control. |
env | RDO environment object or collection. For Visual Basic data environments, use the tag "de." |
err | ADO error object or collection, DAO error object or collection, or RDO error object or collection. |
fld | ADO field object or collection, or DAO field object or collection. |
grp | DAO group object or collection. |
idx | DAO index object or collection. |
obj | Generic object variable. |
prm | ADO parameter object or collection, DAO parameter object or collection, or RDO parameter object or collection. |
prp | ADO property object or collection, or DAO property object or collection. |
qry | DAO QueryDef object or collection, or RDO query object or collection. |
rec | ADO record object. |
rel | DAO relation object or collection. |
rs | ADO recordset object, DAO recordset object or collection, or RDO resultset object or collection. Recordset objects include table, snapshot, and dynaset-style recordsets, and all other allowed cursor types. |
stm | ADO steam object. |
tbl | DAO TableDef object or collection, or RDO table object or collection. Also used for DHTML tables and table bodies. |
usr | DAO user object or collection. |
wsp | DAO workspace object or collection. |
Use Table 9.7 to name elements placed on a Report Designer workspace.
The Hungarian naming standards for many of the controls supplied by Microsoft with Visual Basic appear in Table 9.8.
Menus that are attached to forms carry additional nomenclature rules that identify the natural grouping of those menus. Prefix the names of all second-level menus, third-level menus, and so on, with the name of the menu just above it. For example, consider the menu in Figure 9-1.
Tag | Meaning |
---|---|
lbl | RptLabel control. |
lin | RptLine drawing object. |
pic | RptImage control. |
rpt | Data report module. |
shp | RptShape drawing object, including Rectangles, Squares, Ovals, Circles, Rounded Rectangles, and Rounded Squares. |
txt | RptTextBox control and RptFunction control. |
Tag | Meaning |
---|---|
ani | Animation control. |
cal | Calendar control. See also "dtp" and "mvw." |
cbo | ComboBox control, including the drop-down combo, simple combo, and drop-down list styles, data bound ComboBox control ("DataCombo"), lightweight ComboBox control, or DHTML Select control. See also "icbo." |
cht | MSChart control, or other controls used for bar and line charts. See also "gra." |
chk | CheckBox control, lightweight CheckBox control, or DHTML CheckBox control. |
clb | CoolBar control. See also "tlb." |
clp | Picture Clip control. See also "img" and "pic." |
cmd | CommandButton control, lightweight CommandButton control, DHTML Button control, DHTML ResetButton control, or DHTML SubmitButton control. |
comm | Communications control or component. |
dir | Directory List Box control. See also "drv" and "fil." |
dlg | Common Dialog Box control, whether used for opening files, saving files, selecting print options, selecting colors, selecting fonts, or displaying on-line help. |
drp | Data Repeater control. |
drv | Drive List Box control. See also "dir" and "fil." |
dta | Intrinsic Data control, ADO Data control, or Remote Data control. |
dtp | Date Picker control. See also "cal" and "mvw." |
fil | File List Box control. See also "dir" and "drv." |
fra | Frame control, lightweight Frame control, or 3D panel control. |
gau | Any type of gauge control, other than the Slider control supplied with Visual Basic. See also "sld." |
gra | Graph control, or any control for drawing graphs, but not charts. See also "cht." |
grd | Grid control, FlexGrid control, data bound grid control, and other third-party grid controls. See also "hgrd." |
hgrd | Hierarchical FlexGrid control. See also "grd." |
hsb | Horizontal Scroll Bar control, lightweight Horizontal Scroll Bar control, or Flat Scroll Bar control in the horizontal orientation. See also "vsb." |
icbo | Image Combo control. See also "cbo." |
img | ImageList control. See also "clp" and "pic." |
inet | Internet Transfer control, including FTP, Gopher, HTTP, HTTPS, and any other supported protocol. See also "skt" and "web." |
lbl | Static Label control, or Report Designer RptLabel control. |
lin | Line drawing object, Report Designer RptLine drawing object, or DHTML HorizontalRule object. See also "shp." |
lst | ListBox control, both standard and checkbox styles, data bound ListBox control ("DataList"), lightweight ListBox control, or DHTML List control. |
lvw | ListView control. |
mm | Multimedia control. |
mnu | Menu control, including standard, pop-up, and system menus. |
mpm | MAPI message control. |
mps | MAPI session control. |
mvw | MonthView control. See also "cal" and "dtp." |
ole | OLE Container control. |
opt | OptionButton control, lightweight OptionButton control, or DHTML Option control. |
pic | PictureBox control, Image control, Report Designer RptImage control, or DHTML Image control. See also "clp" and "img." |
prg | Progress bar control. |
rtf | RichTextBox control. See also "txt." |
shp | Shape drawing object, including Rectangles, Squares, Ovals, Circles, Rounded Rectangles, and Rounded Squares, or Report Designer RptShape drawing object. See also "lin." |
skt | WinSock control. See also "inet" and "web." |
sld | Slider control. See also "gau." |
spn | Spin or UpDown control. If used with a "buddy" control (such as a text box), the remainder of the variable name following the "spn" tag should be the same as the post-tag name of the buddy control. For example, if you have a spin control that is a buddy to a text box named "txtYear," the spin control should be named "spnYear." |
sts | Status Bar control. |
sys | SysInfo control. |
tab | Tabbed Dialog control, TabStrip control, or any third-party tabbed section control. |
tlb | ToolBar control. See also "clb." |
tmr | Timer control. |
tvw | TreeView control. |
txt | TextBox control, both single-line and multi-line styles, Masked Edit control, lightweight TextBox control, Report Designer RptTextBox control, Report Designer RptFunction control, DHTML TextField control, DHTML TextArea control, or DHTML PasswordField control. See also "rtf." |
vsb | Vertical Scroll Bar control, lightweight Vertical Scroll Bar control, or Flat Scroll Bar control in the vertical orientation. See also "hsb." |
web | Web Browser control. See also "inet" and "skt." |
Using such "cascading" Hungarian names for menus, the menu items for the menu in Figure 9-1 might have the names listed in Table 9.9.
Menu Item Caption | Menu Item Name |
---|---|
Edit | mnuEdit |
Undo | mnuEditUndo |
(divider bar) | mnuEditBar1 |
Cut | mnuEditCut |
Copy | mnuEditCopy |
Paste | mnuEditPaste |
(divider bar) | mnuEditBar2 |
Bookmarks | mnuEditBook |
Toggle Bookmark | mnuEditBookToggle |
Next Bookmark | mnuEditBookNext |
Previous Bookmark | mnuEditBookPrevious |
Clear All Bookmarks | mnuEditBookClear |
When adding divider bars to a menu, always build the name by taking the parent's menu name, and adding the text "Barx" where x is an increasing number within the parent menu's scope.
Menus can be built using control arrays, where several menus share a common name, but vary by an index number. Only use control arrays for menus where the menu items are truly related and can share a common base of code. For instance, if you have a menu with three mutually exclusive checkable items that all process similar code, they can appear in a control array. Such a control array could use code similar to the following:
Private Sub mnuModeChange_Click(Index As Integer) ' ----- The user changed the mode Dim nMode As Integer ' ----- Put a check next to the correct mode For nMode = MODE_FIRST To MODE_LAST mnuModeChange(nMode).Checked = (nMode = Index) Next nMode ' ----- Update the rest of the display SwitchDisplayMode Index End Sub
Do not use control arrays for elements that are not directly related in their logic. For instance, the common menu items found in an Edit menu (Undo, Cut, Copy, Paste) will generally have coded functionality so different that they could not share a common algorithm. They also should not share a common event procedure.
Incorrect
Private Sub mnuEditAction_Click(Index As Integer) ' ----- This is bad code!!! Select Case Index Case 0 ' ----- Undo related code Case 2 ' ----- Cut related code Case 3 ' ----- Copy related code Case 4 ' ----- Paste related code End Select End Sub
There are legitimate times when you should not strictly follow the guidelines set forth in this chapter. Fortunately, those times are few, and your inclination will be to abandon the conventions in these minor cases.
Some traditional variable names are excluded from the rules of Hungarian nomenclature. Any user-defined data type or Declare statement that you obtain from the API Text Viewer application that ships with Visual Basic, or directly from the Windows Software Development Kit (SDK), should not be altered to conform to the Hungarian dialect described in this chapter. Copy and paste the names as-is directly from the SDK or API Viewer into your code pane.
Event arguments that are generated by Visual Basic need to be left alone. For instance, the standard argument list for the MouseMove event is
Button As Integer, Shift As Integer, _ X As Single, Y As Single
Oh, it makes my eyes hurt just looking at this list. Not a single Hungarian name in the bunch. Still, these arguments fall under the grandfather clause of variable naming; they came into existence with Visual Basic, and too many programmers depend on the consistency by which they appear in every MouseMove event declaration. Do not alter such names to the Hungarian standard.
When you are building a class that contains public module-level variables, name them as if they were used to name Property Get and Property Let routines. Public class variables look like properties to the user of the class; assign such variables property-like names.
3.137.198.183