Coding Standards for Visual Basic
1 IntroDUCTION
These are coding standards for all new projects in Visual Basic Version 4 and above.
2 Constants
These are based upon the standard VB constant format.
Prefix by (e.g. "oa" for Oasis) followed by description in proper case with no spaces or underscores.
The first word of the description should categorise the constant according to the following categories:
Category |
Description |
Format |
Date, time, number formats etc. |
Tip |
Tool tip text |
Tag |
Values stored in control tabs e.g. "Activity" |
Ref |
Reference data type e.g. "CM" for Claimant Status |
AS400 |
AS400 program dependencies - e.g. data seperator, "U"pdate flag etc. |
Wkb |
Constants used in the WorkBasket. |
Example constant: oaFormatISODate
There is no scope prefix as constants should indeed be constant throughout the application.
Where applicable VB's inbuilt constants should be used - e.g. vbHourglass, vbOK, vbTab, rdoOpenForwardOnly etc.
3 Variables
3.1 Scope
Always indicate using the following prefixes:
Scope |
Prefix |
Local |
None |
Module |
m_ |
Global |
g_ |
3.2 Type
Always use the specific type where possible, avoid using Form, Control, Object unless absolutely necessary.
Should always be indicated using the following (lower case) three character codes:
[Do NOT indicate the name of third party vendors, as an SSCommand Button is a Command Button, unnecessary effort.]
Code |
Data / Control Type |
int |
Integer |
lng |
Long |
sgl |
Single |
dbl |
Double |
str |
String |
bln |
Boolean |
dte |
Date |
var |
Variant |
cur |
Currency |
obj |
Object |
col |
Collection |
cls |
Class Module |
txt |
Text box |
lst |
List box |
cmb |
Combo box |
lsv |
List view |
itm |
List item |
tvw |
Tree view |
nod |
Node |
fra |
Frame |
img |
Image |
pnl |
Panel |
lbl |
Label |
pic |
Picture |
cmd |
Command Button |
opt |
Option Button |
chk |
Check Box |
lst |
List Box |
pic |
Picture Box |
frm |
Form |
tlb |
ToolBar |
tmr |
Timer |
MDI |
MDI Form |
3.3 Commonly Used Variables
Variables that will be used throughout a system should be named consistently, as follows:
Var Name |
Representing |
Club |
Club code e.g. "1" = P & I |
Ship |
Ship number e.g. "208267" |
Incident |
Incident number e.g. "007818" |
PolicyYear |
Policy Year e.g. 1997 |
Claim |
Claim Id number e.g. "00003" |
Group |
Group Number e.g. 1049 |
GroupName |
Group name e.g. "Neptune Orient Lines" |
IncidentRef |
Full Incident Reference e.g.Executive\Syndicate\Year\Incident\Claim |
Syndicate |
Claim Syndicate e.g. "L1" |
These variables should be used in accordance with the other rules for variables outlined above, e.g. a modular level variable representing claim id would be named m_strClaim.
4 Procedures
4.1 Naming
Functions should begin with a verb e.g. Retrieve Documents.
Those functions performing a common task should use a common verb as follows:
Verb |
Task |
Retrieve |
Retrieves records from the database |
Load |
Loads an object with a record from the database |
Save |
Saves an object's data back to the database |
Fill |
Fills a control |
Run |
Executes Stored Procedure |
Get |
Get an object from a collection |
Async should prefix the above when using Asynchronous processing - e.g. AsyncRetrieve_RefData
4.2 Layout
Procedural code should be set out as follows:
[All code should be indented one tab, unless otherwise stated, plus the length of the keyword for each level of sub statements i.e. If .. then, While, For Loop]
Comment section set out as follows (no indent):
'**************************************************************************
'Purpose
'Author
'Date
'**************************************************************************
'Comment
'**************************************************************************
'Modifications
'(Initials Date Description)
'**************************************************************************
Date should be in the format dd/mm/yyyy
Author does imply responsibility for the content as do initials in Modifications.
Dims (no indent) 'Dimension all variables at the top of the routine even when maintaining the system.
‘Set on Generic Error Handler
On Error goto ...
Generic Error handler label should have the prefix Err_GenericErrorHandler
Don't use the procedure's name e.g. Err_cmdAdd_Click This is a waste of time and unnecessary. A generic Handler can be copied from one routine to another, without having to rename the labels.
Where more than one error handler is required, the error handlers should be named after the error that is being trapped
e.g. Err_ClaimFile_Update. They should precede the generic handler to ensure that it still traps any unhandled errors.
'Set Up...
Default function return value (if appropriate) e.g. Load_Document=False
Set statements (Assign Objects, Enable or Disable Controls, Create Procedure Level Constants)
'Body of code...
:
:
'Clean Up
Locally created objects should be destroyed here.
Exit Sub/Function (no indent)
Error handler(s). (label, so no indent)
Preferably handle the error and resume, if not then issue a plain english message and any information needed to support the problem. Do not issue messages from dll’s or controls, pass the message back to the user interface and issue it from there.
5 Forms
5.1 General
All forms should comply with Windows Interface Guidelines for Software Design.
In addition to this, main function buttons should have icons and text descriptions. Every screen shown from a main function button should be followed through with the same icon in the top right hand corner of the screen. Never re-use the same icon for 2 different tasks.
Every screen should have a 3D look and feel with the use of dividers and panels, avoid frames for Windows95 NT4 +. To divide a section of the screen, use a black line and a white line next to each other with the black line on the top.
Use the BeCubed MH3DLabel (Arial Font, Bold, Italic, Font Escapement 900) for vertical text on the Left hand side of the screen, to describe the screen's use. e.g. Summary Page.
Each club has it's own logo, display the club's logo on every screen where data is dependant on the selected club.
Use the built in animations, and progress bars to give feedback to the user, as soon as possible, after an option is selected. Don't rely simply on the Hourglass to show that the system is busy, give as much information as possible as to how long the task will take to complete.
Code on forms should be kept to an absolute minimum, calling routines in modules and methods of objects only. However, all of the user interface code should be kept in the user interface, this includes, making controls enabled/disabled, visible/invisible, and controlling the status of the mouse pointer (Hourglass, Default, or somewhere in between) always use the vbConstants, not the magic numbers.
Always set ClipControls Property to False for forms and other containers that have a ClipControls property. This gives you smoother cleaner screen painting and updating.
Never use the DoEvents function in a class module. EVER. (Can cause Re-entry to the module. There will be a better way.) Use sparingly on forms.
Use Tool Tips to explain complex functions. Do not use to point out the obvious. i.e. For a Button marked 'Save' you don't need a ToolTip that says 'Save Changes'
Avoid large numbers of floating forms. If a function requires a lot of data to be filled in on separate screens consider using a Wizard style with a form with different views for different circumstances. Or hide parent calling forms when the current child form is being displayed. As a general rule avoid going to more than 3 levels of Child Form.
Modal Forms. Modal forms are needed less now that a child form can be owned by it's parent. This allows the child to stop the parent being accessed when it is visible but does not stop the rest of the system being used. (This is helpful when filling in data that can be found through other parts of the system). Child forms are minimised and restored when the Parent form is. This means that a controlling toolbar for example can be used to minimise the entire application. To make a parent form own it's child forms,
Use the show command followed by Me if called from the correct form, or the name of another form. e.g. Show frmCaseSearch, Me
You can also use the the generic StartUpPosition of Centre Owner to allow a form to be called from anywhere but still be placed in the centre of it's parent form.
5.2 Initialisation
Each form should contain an initialise procedure (entitled 'InitForm') which loads the controls, sets form size and position etc. (typically this will be called from Form_Load). Forms should NOT be left to draw themselves as per last position they were worked on in the IDE.
5.3 Screen Controls
Tab index positions and tab stop options should be set to ensure correct workflow. If you have a label next to a control use the shortcut key and make the label's TabIndex 1 less than that of the control.
Every screen must have a default and cancel button assigned. e.g Default = True, Cancel = True respectively
Command button names and their shortcut equivalents should be consistent across screens, as follows:
Key |
Command |
Purpose |
V |
Save |
Save data back to database. |
S |
Search |
Search for data based on criteria |
O |
Open |
Open a file and display it's contents |
Familiar Function keys should be maintained from the AS/400 as they are well known and accepted e.g. F12 Cancel, F3 Exit, F4 Prompt
Text boxes should always have MaxLength property set to the corresponding length of the database field.
5.4 Message boxes
Should display applicable icon - e.g. question mark for question and display appropriate buttons for the task. The critical icon should be reserved for use by the Operating System. Or trapped Critical Errors that will result in a shut down of the application.
An appropriate caption should always be set.
Captions should explain the problem in plain English, with either a question about how the user would like to continue, or an explanation of how to correct the problem and continue.
e.g.
Please Enter a Policy Year and then Choose Search again. OK
or
You have Not entered a Ship Name or Number. Do you Wish to Continue ? Yes No
Two carriage returns should be used to divide multiple lines of text - e.g. strMsg1 & vbCR & vbCR & strMsg2
6 Classes
6.1 Properties
All properties should be exposed using Get/Let/Set routines with their corresponding local variables dimmed as Private in the declarations section under the heading 'Local Property Variables'.
These variables should follow the standard variable naming conventions outlined above and contain the same name as the property they represent e.g. m_strIncident for the Incident property.
The parameter to a property Let or Set should always be named NewValue and should be prefixed with its type code - e.g. strNewValue.
6.2 Clean Up
All module level objects should be destroyed in the class terminate event.
Note : All references to other objects must be destroyed before the terminate will execute. If not done can cause objects to not terminate causing memory leaks
6.3 Comments
As well as the Comments section at the start of the procedure, additional explanatory comments should be placed at the relevant point in the code.
These should be used to explain why something is being done as opposed to merely stating the obvious, e.g.-
'As the collection will contain a simple list of dates, the generic object is used.
Dim objGeneric as New clsGeneric
is useful, whilst...
'Create a generic object.
Dim objGeneric as New clsGeneric is not.
Always use correct grammar and punctuation, avoid abbrevs, jargon and TLA's.
7 Visual Basic IDE
The following options should be set: