polyphonicstudios

vbstyle

Please note: If you want to be a great programmer, please go here. I strongly encourage you to move to a different language. There are awesome advances in technology since VB 6 was invented. I leave this document for historical purposes. I doubt I'll make any more changes. -Scott 

This document attempts to describe some very basic but important guidelines for the coding of Visual Basic programs. As you browse through the hundreds of these so-called coding standards, keep this in mind: You must write your code so that others who are far less experienced than you can read and follow your logic. In these days of 2 Ghz cpus and high speed harddrives, the days of writing horrible but "efficient" code are over. It is inexcusable to create unreadable code. If you are spending hours trying to write the "fastest" routine you can think of to display a progress meter, then your priorities are severely perverted and you should choose a different profession.

Rules of Thumb

  • The less code the better.
  • It is more important that the code be understandable than "readable".
  • It is more important that the code be "readable" than "efficient".
  • Everything that you explicitly create, you must also explicitly destroy.
  • Always set the Auto Increment entry of the Visual Basic Project Properties dialog in the Make section.
  • Don't use the underscore character ("_").
  • Turn on all of the toolbars.

Off Limits VB Commands

The following VB Commands should never ever be used:

The End Statement

The End statement causes an immediate end to all processes. It leaves much of the memory allocated to the Visual Basic program "orphaned" as the memory is not (necessarily) de-allocated. Orphaned memory cannot be re-used by other programs. Using the End statement to forcefully unload an ActiveX EXE server is considered bad programming. Apply the rule: Everything that you explicitly create, you must also explicitly destroy. Visual Basic will not unload an EXE, DLL or OCX when a form is loaded or an object was not loaded. As you are developing, you can add a statement such as the following to ther Terminate event of a class or Unload event of a form:

debug.print "frmSalesInvoice_Terminate"

If you're in the IDE and your program doesn't completely end by itself, that's a dead give away that you created something that Visual Basic couldn't unload some thing. Usually a form.  Don't compile until you get this fixed.

The Stop Statement

The "Stop" statement should not be used. Chances are good that you'll forget to remove it from the source code. If you don't test thoroughly, the Stop might make it all the way through deployment. Set break points and watches instead.When debugging, before running the program, press the F9 key to set a breakpoint - or click in the far right margin next to the line you wish to stop at. Then you can walk through the code using F8 (a line at a time) or Shift F8 (execute a line but don't step into it).

ActiveX Components

The most important guideline is simply don't bother creating a class at all unless you know how Visual Basic ActiveX components work and what it means to create a class. Classes are Types. And coding Types take work, lots and lots of work, work that doesn't even really involve programming until much much later. If you sit down to create a "Sales" class and fill it full of stupid properties like "CalculateTax", learn a different language.

Project Descriptions

Always give an ActiveX EXE/DLL project a description. The project description entry can be found on the 'General' tab of the Visual Basic Project Properties dialog. This description appears in the list of Visual Basic Project Components / References dialog.

Binary Compatibility

It's a good idea to construct your ActiveX project using Binary Compatibility. This powerful feature of Visual Basic monitors the public interface of your component. Set up Binary Compatibility using the following guidelines.

  1. Create a folder under the project folder called Release
  2. "Make" and then test your component in the project folder.
  3. Copy the tested EXE or DLL into the Release folder.
  4. Set the Binary Compatibility option in the Visual Basic Project Properties dialog to the EXE or DLL in the Release folder.

After following the above instructions, Visual Basic will warn you if you make a change to the public interface of your component that will cause clients of the component to fail unless they are also re-compiled. Constructing your component with Binary Compatibility set from the beginning forces you to carefully consider each and every change you make to your public interface.

Constants

Visual Basic's language specification suffers from the inability to define a string constant. So all manner of guidelines exist for creating pseudo-string constants. There's really only one way to correctly code a string constant and it really isn't even a constant. It's an atom resource. Atoms are used to "localize" the text of a program so that multiple human languages can be used. So in the end, just forget about creating a string constant, it's not going to happen.

Using the Const Statement

There's no such thing as a Public constant. All Const statements should be declared Private by using the default, which is no declaration at all. If you need more scope than Module level scope, use an Enum.

Don't flood the Declarations section full of Const statements. Use Enum instead.

Const statements should always be all upper case. They should never be more than two words. Keep the use of the "_" character to an absolute minimum. If it's not numeric, it can't be considered a constant. If it is a string, it is either a literal in double quotes "CompanyName" or it needs to be an atom in a resource file so it can be localized.

Dealing with Field Names

Do not create constants for Field names or Field ordinals. Use the String version as in rsSomeRecordset.Fields("CompanyName").Value. It's easier to read and modify. If you do your job right, you won't be changing field names in the future anyway, thus negating the only reason for using a constant in the first place.

Never,ever, fucking use field ordinals. Got that?

Using the Enum Statement

Public constants are coded with the Enum statement in the declarations of a Module or Class. Force yourself to think in terms of multiple possibilities. The Enum statement creates a group of Consts that can be automatically typed into your code using the AutoComplete feature of Visual Basic for passing parameters.

Do not specify a value unless you are forced to because your are declaring constants to be used with an API.

Naming Convention

When coding Enum, attempt to come up with a very short unique identifier prefix for both the Enum and the individual members. Ignore the convention guidelines out there. Do not specify a scope prefix (it's all public, dammit). Do not specify a type prefix (it's all numeric dammit). Specify instead a short abbreviation of the Enum type as in:

Public Enum 
    cbxStyle     
    cbxsNormal     
    cbxsDropDown 
End Enum

Where cbx is an acronym for Combo Box Extended and the "s" in cbxsNormal stands for Style. It's hard to make these abbreviations make sense. Some guidelines specify a Company name moniker but that can get dicey. The constants will be grouped together in the object browser by the acronym that you come up with so don't be surprised if takes a while to come up with something that makes sense. The acronym needs to be extremely short (less than 5 characters) so as to be unnoticeable in the object browser.

Code Layout

Remember the golden rule of Visual Basic programming stated in the preamble of this document. You must write your code so that others who are far less experienced than you can read and follow your logic. The way your code looks is far more important than how fast your code runs. Just remember that. The reason for this rule is quite simple. Well crafted and well thought out code runs fast and usually works better. Sloppy, thrown together, unreadable code, runs slow and breaks easy. Tell me the truth, would you rather sit and spend the day looking at Donna Summer's trashy, cocaine induced vomit that she calls art, or would you rather marvel at the majesty of Michelangelo's David?

Use Appropriate Indentation

The convention to indent every line in a procedure is stupid. Learn to use the Procedure View/Full Module View buttons in the lower left corner of the IDE. Turn off the Default to Full Module View flag in the in the General tab of the Tools Options dialog. The IDE promotes the encapsulation of programming logic with the Procedure View. You should only ever look at one procedure at a time. Looking at the entire code stream of a module is extremely distracting and error prone. This leads to the stupid indent all lines in a procedure convention.

Indent logical blocks of code. All code between If and Else and End If must be indented. All Cases within Select must be indented. All code after a Case must be indented. All code within a loop must be indented.

Statement Line Counts

Block If Statements

The objective of writing solid Visual Basic code is to eliminate code where possible. Never code a block If when there is only a single line of code in the block.

If bSomeFlag Then
     X = X 
End If

Should be coded as

If bSomeFlag Then X = X

The exception is when you want to put a break point on the X = X rather than the If but try to remember to put it back to one line.

Multiple Statements per Line

Concatenation of multiple statements per line using the ":" separator is proper when the individual lines concatenated are tightly related as in:

X = vNewValue1: Label1.Caption = X Y = vNewValue2: Label2.Caption = Y

This convention can cut way back on the amount of junk the reader has to look at.

Multiple Dims per Line

Multiple Dims on a single line is proper. Whoever says it isn't is an idiot. You just have to remember that if you do not specify the type, then the type is a Variant (the default type). The reason for prohibiting the use of multiple declarations is because of this "feature". But those same people that prohibit this usage insist that you use Option Explicit which invalidates the prohibition.

Anyways, do you really care what the type is? No, not really. Sometimes you do, so its nice to scan across a few lines of multiple Dims than it is to scan down the entire page. But then again, why are you writing code that requires so many declarations? Isn't it more probable that the code you are writing that requires a large number of Dims has got away from you and that one or more utility routines with far few local variables is more appropriate?

Line Continuation Characters

Do not use the line continuation ("_") character to break up a single line across multiple lines. Breaking up your single line statement makes it almost impossible to read. It does not aid in readability. Anyway, it takes forever to split the line up and indent. It also breaks the rule for reducing the lines of code.

The exception to this rule is when embedding SQL statements. But this practice should be avoided at all costs. Use either the Data Environment or stored procedures. Learn how to use and code query parameters.

Why is your code line so long? Long lines of source mean that you have an overly complex formula that needs to be broken up into stages. Or the code is a message box. Look, don't worry about message boxes. They matter so little during code troubleshooting. Put the invocation of a message box all on one line so as to get it out of the main flow of the program text.

Complex Formulas

Complex formulas need to be broken into parts if the formula cause the reader to scroll horizontally. In this case, the use of temporary variables is strongly encouraged. But use common sense. If the actual details of the formula are not that important, then put it all on one line.

Candy Machine Interfaces

Candy Machine Interfaces is a term reserved for those functions that have way more parameters than are necessary in an object oriented environment. Many of the CreateSomeObject methods have Candy Machine Interfaces and allow you to specify a large number of properties to set all at once when an object is created. Forget that. Create the object with the smallest amount of properties required and then set the individual properties afterwards.

Use common sense. If the actual details of the function call are not that important, then put the function call all on one line.

If you are using a library of functions that have huge parameters lists like described here, replace it. The developer of the library hasn't learned a thing in the last five years.

Property Procedures

Individual Property Get/Let/Set procedure definitions should be around 5 lines. Property procedures are usually restricted to accessing private member variables. If a property procedure is lengthy, it probably hasn't been well thought out.

Sub and Function Routines

Sub and Function routines should never be more than two full screens worth of lines, including comments. To cut back on the comment line counts, place the comments at the end of the line of code they are most associated with.

Always refer to the name of the routine. Does the code you are writing accurately reflect what is expected of a procedure by that name? If your procedure does way more than what the name implies then create a private sub or function to encapsulate some of the more icky bits. But don't go crazy. Some procedures are unusually complicated and intricate and are subsequently longer than usual. These routines need to be commented rigorously and the names of entities need to be very self-explanatory.

Declarations Section

The Declarations section should only be a screen's worth long. Each variable should be declared on a separate line. Like variables should be grouped together, e.g. All Const go together. All Public likewise, etc.

Long Declarations Sections with many lines should always raise your eyebrows. You can't possibly have that many module scope variables can you? Lots of Win32 API declarations is avoided by using Type Libraries.

In general, you should only have an insignificant number of Public (global) variables. Always declare your variables as Private and then if you think of a really good reason to change it to Public then do.

Empty Procedures

Delete empty procedures outright. Start the program using the "Start With Full Compile" option. Visual Basic will locate any references to deleted procedures. Either delete or re-code those references. Empty Procedures do produce real code that doesn't do anything except add to the byte count of the finished product.

Site

Changes
Index
Search

 

User

 

Log In

 
 

Last Modified 4/23/07 3:08 PM