Tuesday, December 26, 2006

Coding Standards for Visual Basic (2)

Procedure & Coding Formats

Procedure Format Standards

Coding of Procedures/Sub-routines should be done in such a way as to ensure the code is as easy to read as possible. This involves the indentation and spacing of code in order to distinguish between specific processes and functions within the code, as shown in the example below.

Private Sub cmdButton_Click()
Dim strString as string
Dim blnBoolean as boolean
On Error Goto ErrorHandler

''''''''''''''''''''''
' This is an example '
''''''''''''''''''''''


strString = "Hello"

If blnBoolean then
If Function(strString) then
Exit sub
End if
End if

Exit Sub

ErrorHandler:

Msgbox err.number & ":" & err.description, vbcritical, _
"cmdButton_Click"
End Sub

The same code without spacing or indentation proves much more difficult to read (see below).


Private Sub cmdButton_Click()
DIM strString as string
DIM blnBoolean as boolean
On Error Goto ErrorHandler
''''''''''''''''''''''
' This is an example '
''''''''''''''''''''''

strString = "Hello"
If blnBoolean then
If Function(strString) then
Exit sub
End if
End if
Exit Sub
ErrorHandler:
Msgbox err.number & ":" & err.description, _
vbcritical,"Button Click
End Sub

Procedure specific variable declarations should be grouped together at the top of the procedure. Where appropriate attempt to group variables by common threads (i.e. Variables associated with particular processes or with common functions.) and then group by
datatype. This rule should also be applied to variables declared as Option Explicit


Try to keep procedures to a manageable size. If this requires the movement of code to sub-routines or functions then do this. Although the code may be split it will still be much easier to read and understand in smaller chunks.


Langauge Statement Standards

The following are guidelines to a few language statements.

IF Statement
The IF statement should be indented at each if level. The corresponding ELSE should align with the IF, as shown

Eg1

If blnBoolean then
If blnFunction(strString) then
Exit sub
End if
End if


Eg 2

If blnBoolean then
If blnFunction(strString) then
Exit sub
Else
IntCounter = intCounter + 1
End if
Else
Msgbox "Boolean is false"
End if


Avoid creating IF statements over six levels deep as the comprehension of IF statements becomes increasing difficult the deeper they become.

Select Case Statement


Select Case intMenuItem
Case 1
frmFinance.Show
Case 2
frmStock.show
Case 3
If blnSecurityPass Then
frmPass.show
Else
Msgbox "You do not have access authority."
end if
End select


For...Next Statement

For intIndex = 1 to intLastRecord
If datStartDate(intIndex) > now() then
blnErrorFlag(intIndex) = True
Else
blnErrorFlag(intindex) = False
End if
Next intIndex


note: the NEXT statement contains a
reference to the counter (intIndex),even though it is not required for functionality. This should be done for
all FOR...NEXT loops to add clarity, especially where loops are embedded
within loops.


While...Wend Statement

Dim intCounter
intCounter = 0
While intCounter < 20
intCounter = intCounter + 1
Wend


GOTO Statement

The GOTO statement should be avoided at all
times as it can create confusing jumps in code. The notable exception to this rule is the
'On
Error GoTo'
statement.

Form Design Standards

Forms and Controls

Windows Standards should be used for all forms and controls unless the customer has specified otherwise.

Where possible, Controls should be set to 'Locked = True' rather than 'Enabled = False' to allow greater development control over colour as well as clarity of control content for the user.

An application wide font of MS Sans Serif size 8 should be used to provide system conformity. This, of course, is subject to sensible variations to accommodate user and formatting requirements.

Confirmation and Rejection command buttons should use 'OK' and 'Exit' as their text, in order to match the Windows standard. Any deviation from this should only be at the customers specific request.

Enabled or non-locked controls such as TextBoxes and ListBoxes should have a 'Fixed Single' Border Style property and '3D' Appearance. Labels should have an Appearance property of 'Flat'.


Menus
All major forms should possess a menu bar unless otherwise specified by the user. The menu bar items should be presented using the Windows standard menu style and naming conventions (i.e. Hierarchical menus with Hot keys using item names the same as, or similar to Windows menu item names - see example below). Where there are Command Buttons available on the form, then these activities should be included within the menu where relevant.

Eg.

File View
Help

Add
Forecasts Help F1

Modify
Invoices Contents

Delete

Exit


Error Handling
All sub-routines, where even a small degree of processing is involved, should contain error handling.
System errors should not be displayed to the user, the code should control the system errors, displaying a user friendly and informative message relating to the processes being undertaken at the time of the error. Eg.

"Unable to retrieve the selected record."

The system error number, description and the location where it occured (form/module and procedure) should then be written to a log file. This provides valuable debugging information and can then be referenced by the System Administrator. It is preferable for the Error logging routine to be a common function, which could be held in a
DLL.
Where there is any database connection and utilisation the error handling must be comprehensive. Again, it is preferable for all database error handling to handled by a common function which can filter the database errors.

In the absence of a common Error Handling Routine for the Project then errors should be handled as shown in 'Procedure and Coding Formats'. Ensure the error message box contains some reference to where the error occured (e.g. the message box title bar) for easier debugging. Where there is any database connection and utilisation ensure that the error handling is comprehensive. The user should not receive any system messages, particularly with regard to ODBC errors.

Source : Unknown

Coding Standards for Visual Basic (1)

Introduction

The purpose of this document is to provide quality guidelines for the
control of code developed in Visual Basic, ensuring some degree of
discipline is employed in the development environment. In addition these
standards are designed to increase readability, maintainability,
reliability and portability of Visual Basic programs.


Contents:


  • Comments
  • Sub-Routines and Functions
  • Forms and Modules
  • Naming Standard
    • General Objects
    • Database Objects
    • DataTypes, Variables and Functions
    • Variables
    • Functions

  • Global Variables & Constants

Comments

All code should contain a degree of commenting to lend clarity to
the processes taking place in the procedures, functions, events etc. This
is not only useful


for any future development or enhancement that may take
place but provides useful reference for the current developer. Comments
within the code should be brief and informative, containing as little
technical jargon as possible. Some example code is shown below.


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Check if user has amended a retrieved record to ensure '
' that amendments are not accidently cancelled '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

If Me.Caption = FstrFormCaption(RETRIEVE_RECORD) Then
If blnHaveDepFieldsChanged(Me) Then
strTitle = "Clear Form"
strMsg = "Are you sure you want to clear the " _
& "form and lose any changes made?"
If Not OkToProceedMsgBox(strTitle, strMsg) Then
'''''''''''''''''''
' cancel selected '
'''''''''''''''''''

Exit Sub
End If
End If
End If

''''''''''''''''''''''''''''''''''''''''''
' close down current action form if open '
''''''''''''''''''''''''''''''''''''''''''

For I = 0 To Forms.Count - 1
If Forms(I).Name = "frmCurrActions" Then
Unload Forms(I)
End If
Next I

Sub-Routines and Functions

All user defined Procedures and Functions (these are non-object
generated sub-routines such as Events) should be prefixed by a comments
box providing a brief description of the sub-routine's purpose or function
and it's relevant calls. Comment templates for most sub-routines are shown
below.

''''''''''''''''''''''''''''''''''''''''''''''''''''
' Object :
' Description :
'
' Calls To :
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

''''''''''''''''''''''''''''''''''''''''''''''''''''
' Procedure :
' Description :
' Parameters :
'
' Called By :
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

''''''''''''''''''''''''''''''''''''''''''''''''''''
' Function :
' Description :
' Parameters :
'
'
' Called By :
' Value Returned :
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

''''''''''''''''''''''''''''''''''''''''''''''''''''
' Property :
' Description :
'
'
''''''''''''''''''''''''''''''''''''''''''''''''''''

Forms and Modules

Each individual Form, Module, Class Module and ActiveX control should also
contain a comments box, describing the overall purpose behind the object.
This comments box should be positioned at the top of the code, before the
'Option Explicit' Section. Templates are shown below. All sections of this
comments box should be completed apart from the Modification History,
although a blank modification history should still be provided. If a
developer is required to add a fix or modification to another developers
code, even prior to release, the modification history must be completed by
the developer providing full explanation of the changes made and the
reason for the change. All Database tables that are referenced within a
form or module should be listed. These should be listed next to the
'Database' heading in the comments box.


''''''''''''''''''''''''''''''''''''''''''''''''''''
' Module :
'
' Description :
'

' Database :
'

' Author :
'
' Date :
'
' Modification History:
'
'
' Author Date Reason Comment
' --------- --------- -------- ---------
'
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Form :
'
' Description :
'
' Database :
'
' Author :
'
' Date :
'
' Modification History:
'
'
' Author Date Reason Comment
' --------- --------- -------- ---------
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Naming Standards

Objects

All controls added to a Form should be named according to their content or
function to allow greater understanding of their function. Avoid leaving
any controls with their default names. E.g.,

where Text1 is the default name for a TextBox displaying a Forecast total,
it could be renamed…

    txtForecastTotal
where more than one total is displayed or 
    txtTotal

where it is the only total on the form.

All control names should be prefixed with an appropriate three letter
acronym (in lower case) describing the controls type. Below is a list of
examples.

View Image

Database Objects

All database objects should be named according to similar standards.

VIEW TABLE

DataTypes, Variables and Functions

DataTypes should also be prefixed to allow for greater understanding of
the code.

VIEW TABLE


These rules also apply to the declaration of function names, where the
returned value should be reflected in the Function name.Examples:



Variables


Dim intCounter as integer

Dim blnFlag as Boolean


Functions

Function blnCompareTotals(intForecastTotal as Integer) as Boolean

Global Variables & Constants

Globals

For shared Projects (VBPs) Global variables should be defined in a common
module (modGlobals), otherwise Globals should declared in one place in the
project being developed. This is to ensure a central reference is
available and avoid any naming conflicts.

In order to identify globals within code prefix them with 'g'. Therefore,
intCounter would become gintCounter.

When creating a new Global variable ensure a brief description of the
variable is provided for reference by other developers. Example:


'Indicates if user has authority
Global gblnAuthorityFlag as Boolean


Constants



Constants should be entered in Capitals.



Example
Const HIGHLIGHT = &H8000000D&


All public constants should be declared within the globals module
(modGlobals) in the Constants section provided. As with the global
variables, a brief description should be provided, either for groups of
constants or individual ones.