Instantiation Standards

Now that you have decided on names for your variables, constants, controls, and other elements of your application, it is time to put them into active use. Instantiation is the process of adding declaration elements to your source code.

Instantiation of Variables

Because all of your modules will contain the Option Explicit statement, you are required by the Visual Basic development environment to declare every variable before use. Take care in declaring your variables, as these declarations will determine the range of values available for each variable. Declare your variables in known locations, and in a consistent manner.

Visual Basic contains six types of variable declaration: global, module, local, static, passed, and redeclared. Always place global variables in the Declarations section of a standard code module, never in a Form. The look of these variables is pretty consistent.

Public glCustomerID As Long

The declaration begins with the Public keyword, not the antiquated Global keyword. It is quickly followed by the letter "g," the Hungarian prefix for global variables. And if a consistent declaration head was not enough, the end of the line always contains the appropriate As clause (except in VBScript).

Module variables would almost be indistinguishable from global variables were it not for the replacement of the Public keyword with the Private keyword. They always appear in the Declarations section of the appropriate module. While Visual Basic allows you to declare these variables with the Dim keyword, always use the Private keyword instead.

Private msLoginName As String

Module variable names begin with the "m" scope prefix, and are followed by the appropriate As clause.

Your application will generally have more local variables than any other type. In fact, you should strive to make most of your variables local in scope. Global and module variables are convenient, but they carry risks (read all about those risks in Chapter 2). You declare local variables within a procedure. Visual Basic affords you a lot of freedom in the placement of your declared variables; you can declare a variable almost anywhere in your procedure, even as the very last line. However, spreading out your declarations in this manner makes maintenance of your source code more cumbersome. Instead, place the declaration of all local variables at the very top of your routine, just after the introductory comment.

Private Sub txtStatus_Change()
    ' ----- Update other fields based on the current status
    Dim sActiveStatus As String
    Dim nCounter As Integer
    ...

Except within VBScript code, always include the appropriate As clause, plus a useful Hungarian variable name. If you have variables in many routines that share a common purpose, give them the same name throughout your code. For example, many times you will include For loops in your source code. Instead of using a variable name such as x or i (dreadfully non-Hungarian names) as the loop variable, use nCounter, or a similar consistent name. Such consistency will make it easier for others to follow the thought process of your source code.

Static variables appear within procedures, but act like global variables, retaining their values from the end of one use of the routine to the start of the next use. Visual Basic allows you to preface the procedure declaration with the Static keyword to cause all variables within the routine to automatically assume the role of static variables. However, you should shun this method; instead, use the Static keyword before each variable that needs to be static. Do not forget to include the "x" Hungarian scope prefix before the variable name.

Public Function RunningTotal(nNewValue As Integer) _
        As Integer
    ' ----- Maintain a running total of values.  Return the
    '       current total on each call to the function. If
    '       nNewValue is 0, clear the total.
    Static xnTotalSoFar As Integer

    If (nNewValue = 0) Then
        xnTotalSoFar = 0
    Else
        xnTotalSoFar = xnTotalSoFar + nNewValue
    End If
    RunningTotal = xnTotalSoFar
End Function

When declaring static variables in a local procedure, place them just after the declarations of local variables. The use of static variables can sometimes hide logic errors, especially when used in conjunction with recursive procedures. Use static variables, but use them carefully.

Passed variables are those that are listed as arguments of a procedure declaration. Consider the Unload event for a form.

Private Sub Form_Unload(Cancel As Integer)

This event procedure contains a single passed variable named Cancel. Variables can be passed by value (local changes to the variable are not passed up to the calling routine) or by reference (changes made to the variable are reflected in the original variable used in the calling routine). By default, all passed variables are passed by reference. It is not necessary to specify the ByRef keyword for pass-by-reference variables (although it is required in Declare statements), but you will need to use the ByVal keyword to specify pass-by-value. If you do pass in a variable by value, never modify its value within the procedure or in a subordinate procedure. Although this is allowed in Visual Basic, you should declare a separate local variable and use it instead of treating a by-value passed variable like a local variable.

Visual Basic allows you treat passed variables as optional arguments by using the Optional keyword. If you want to use the IsMissing function to test whether an optional argument was supplied, you must declare the argument as a Variant. Use the proper Hungarian prefix ("vnt") for such optional arguments.

The final type of variable is the redeclared variable. These are array variables that are initially declared without array subscripts using the Public, Private, or Dim statements, or as an element of a user-defined type, and then later resized using the ReDim statement.

Dim asDayInfo() As String
...
ReDim asDayInfo(1 To nDaysInMonth)

Visual Basic allows you to create a new variable using the ReDim statement (without an initial Public, Private, or Dim statement for that variable). Do not employ this method of variable declaration. Instead, always initially create resizable variables using a Public, Private, or Dim statement, and later resize it using the ReDim statement.

Never change the number of dimensions using the ReDim statement. If you intend to use a certain redeclared variable with two dimensions, never give it fewer than two dimensions, or more than two dimensions, when using the ReDim statement, even though this is allowed. Changing the number of dimensions throughout your source code also changes the expectations for the use of the variable. If you originally redeclare a variable with two dimensions in one routine, and later redeclare it again with three dimensions in another routine, you violate the original definition of the variable when the first ReDim statement was employed.

When declaring variables in versions of Visual Basic other than VBScript, only include a single variable with each Dim, Private, and Public statement. That is, each variable should be declared on a line by itself.

Incorrect

Dim nCounter As Integer, sCustName As String

Correct

Dim nCounter As Integer
Dim sCustName As String

Declaring variables in VBScript is a little different from the same process in other flavors of Visual Basic. With Variant being the only type of true non-object data type, the As clause is irrelevant. Still, variables are declared in VBScript for specific purposes, with some of those purposes requiring date variables, some string variables, and some numeric variables. It may be useful to visually group variables of like data type during declaration. In such cases, it is permissible to place more than one variable within the same Dim statement, but only if they start with the same Hungarian prefix.

VBScript Only

Private msCustName, msCustPhone, msCustCity
Private mnCounter, mnOrdersSoFar
Private mdtOrderDate, mdtShipDate

Instantiation of Constants

Place constant definitions in the Declarations section of a module, form, class, and so on. Although Visual Basic allows you to declare constants in any procedure, you must shun this practice. Placing all constants in the Declaration sections of your application makes the quick location of such constants easy.

Always precede the definition of a constant with either the Public or Private keyword. Private constants can appear in any Declarations section, but a Public constant must never appear in a Form module (Visual Basic will not permit such a definition). If you find a need to declare a set of related incremental numeric constants, consider an enumerated data type instead.

Like variables, constants can be declared with an As clause.

Public Const MAX_ADDRESSES As Integer = 12

The use of the As clause is optional when a type declaration character is attached to the constant's assigned value. (See the "Data Typing of Literals" section later in this chapter for a discussion of type declaration characters.) If you are declaring constants of type Currency, Double, Integer, Long, or Single, use the appropriate As clause, or follow the literal value of each constant with the appropriate type declaration character.

Public Const MAX_ADDRESSES = 12%

When declaring constants of type Boolean, Byte, Date, String, or Variant, use the As clause to correctly identify the constant.

Some versions of Visual Basic make Year 2000 compliance difficult by trimming off the first two digits of a four-digit year from literal dates appearing in the 1900s. In those versions of the Visual Basic development environment, if you type in the date literal #9/23/1999#, Visual Basic will conveniently change this to #9/23/99#. To overcome this deficiency, always enter date literals from the 1900s in string format.

Public Const PROCESS_BASE_DATE As Date = "1/1/1980"

Instantiation of User-Defined Types

User-defined data types always appear in the Declarations section of some type of module. Always include the Public or Private prefix to the data type definition, remembering that Visual Basic will not allow public user-defined types in a Form module.

Instantiation of Enumerated Data Types

Enumerated data type sets always appear in the Declarations section of a module, form, or other similar user interface class. When declaring the data type, always include the Public or Private keyword before the declaration. A Private enumerated data type can appear in any type of module, but a Public enumerated data type may only appear in the Declarations section of non-form modules.

Instantiation of Line Labels

Line labels are simple to use, and as such, the rules surrounding their use are simple too. The only real rule has to do with placement of the label. Although line labels can appear on the same line as logic statements, such lines are no longer label lines, but true logic lines. Line labels should always appear on a line of their own. Even comments should appear after the line label line.

Correct

DetermineResult:
    ' ----- Find out if processing was successful
    mbResult = True

Incorrect

' ----- Find out if processing was successful
DetermineResult: mbResult = True

If you have a line label accessible section of code that appears in numerous procedures, use the same line label throughout the application for the similar sections. For example, if you have an error handler that appears in many of your routines, a label with a name such as "ErrorHandler" will make the label name more meaningful as someone peruses your source code.

ErrorHandler:
    GeneralError "frmMain.Form_Load", Err, Error$
    Resume Next

If you call a subroutine that has no arguments as the first statement of a multi-statement line, you will notice a display anomaly in some versions of the Visual Basic development environment. If you have a subroutine named DoSomeWork, and you write the statement

DoSomeWork: lblWarning.Visible = True

Visual Basic will correctly process this multi-statement line by first calling the DoSomeWork routine, then setting the Visible Property of the lblWarning label to True. However, the code window within the development environment will interpret the DoSomeWork component as a line label, and force the line to the left border of the code window. In order to defeat this interpretation, either avoid multi-statement lines, or use the Call statement with such routines.

Call DoSomeWork: lblWarning.Visible = True

Instantiation of Procedures

Procedures include functions, subroutines, event procedures, and the various forms of property procedures (Get, Let, and Set). It is impossible to write complex Visual Basic applications without procedures, so their declaration is key to the core functionality of your application. Procedure declarations consist of four parts: qualifiers (Public, Private, Friend, and Static), the procedure name itself, the argument list, and the return value (for Functions and Property Get procedures).

Public Function GuessMyAge(sName As String) As Integer

Always prefix your procedure declaration with either the Public, Private, or Friend keyword. Public and Private procedures can appear in any type of code module, although the use of Public form procedures should be limited to those instances where the form must interact with another form or module. The Friend keyword only appears in class module procedures, and is in some ways a combination of Public and Private. The Static keyword must never be used to qualify a procedure declaration. If you need all of the local variables within a procedure to be static in nature, declare each variable individually with the Static keyword.

Function procedures and Property Get procedures both return values of a specific type. When declaring Functions and Property Get procedures, always include an As clause to specify the return type of the procedure, even if the return type is the default Variant data type. This will make it clear to the caller of your procedure what type of data to expect. Visual Basic can also weed out some incompatible conversions of function return values into variables.

The argument list of a procedure consists of zero or more passed variable names. Each of these names must use a proper Hungarian name as if each variable were declared locally. Each of these names must also be followed by the appropriate As clause (except for ParamArray arguments). By default, all arguments are passed by reference (an implied use of the ByRef keyword). If an argument should be passed by reference, the use of the ByRef qualifier before the argument name is not needed. However, you must use the ByVal keyword if you want an argument to be passed by value. ByVal arguments must not be modified within the body of the procedure.

There are two special types of variables that can be included in the procedure argument list. Optional arguments are preceded by the Optional keyword. While you can declare an optional argument as almost any Visual Basic data type, you will not be able to use the related IsMissing function unless you declare the optional argument as a Variant. Optional arguments can include a default value.

Optional fsTemperature = 98.6!

If there is any chance that the meaning of the default value will be unclear to the reader of your source code, declare a constant indicating the default value, give it a descriptive name that makes the meaning of the constant clear, and assign this constant as the default value of the optional argument.

Optional fsTemperature = NORMAL_BODY_TEMP

The other special type of argument list variable is the parameter array variable, which is always preceded by the ParamArray keyword. Only one parameter array argument can appear in the argument list, and it must be the last argument. This argument is actually an array of Variants by definition, so it does not require the use of the As clause.

Instantiation of Declares

As mentioned in the "Nomenclature for Declares" section earlier in this chapter, the rules surrounding the use of Declare statements generally follow the format supplied by the vendor of the DLL from which you are declaring the procedure. Still, there are a few guidelines that can help make your use of Declare statements more consistent.

As to the location of Declare statements, they should all appear in the Declarations section of your primary code module. Always prefix such declares with the Public keyword. It is permissible to place Private Declare statements in other modules when you have:

  • A code module, form, class, etc., that is designed to be "self-contained." Such a module can quickly be added to any new Visual Basic project, and will immediately work because it contains all coding aspects needed to correctly execute the code contained within the module.

  • A class module that is designed to be "isolated" from the application in which it appears. Classes are useful for creating "black boxes" of code and data, usable through limited points of access, much like using the on and off ramps of a free-way. API calls used within the class can be declared privately within the Declarations section of the class.

The remaining standards surrounding Declare statements exist to make a statement complete and clear. Consider this commonly used API call from the API Text Viewer supplied with Visual Basic.

Public Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, _
    ByRef lParam As Any) As Long

Always include the ByVal or ByRef keyword in front of each procedure argument. By default, these arguments are passed ByRef. If one of these keywords is missing for a parameter, the ByRef keyword will generally be correct. When in doubt, reference the vendor's original documentation.

If a procedure was originally declared by the vendor of the DLL as a function, do not declare it as a Sub. Correctly declare it as a Function, and either capture and ignore the return value, or use the Call keyword when using the function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.48.181