VB6 Programming Standards

Level:
Level2

Coding standards - there's an expression that will strike fear and anger into the hearts of many programmers. Don't let that happen to you. Coding standards aren't about rules that have been carved in stone, they're about practical guidelines that in the end will make your life as a programmer easier and your programs better. My intent in presenting this page isn't to hand down a set of programming commandments, but to offer a set of guidelines for good coding. Some of what's presented here are things I've learned on my own, often the hard way, and some are things I've read about and implemented. Whatever the source, they've worked well for me.

Parts of what you'll find here you can also find in more depth on my documentation and naming convention pages. On this page, I'll focus primarily on the guidelines I use for application design and code construction. Since this is only a simple web page there won't be a lot of depth to each section, but hopefully it will be enough to get you started. If you're interested in a book length discussion of coding standards, I highly recommend that you read Code Complete by Steve McConnell, published by Microsoft Press. It's the best book on good programming practices that I've read. Many of the concepts you'll find here were taken in large part from McConnell's book.

Application Design

  • Introduction
  • Program Design
  • User Interface Design

Introduction

There are many issues involved in building a good design. You not only have to consider the design from the programmer's point of view, but also from the user's point of view. I've divided this section into program design - meaning the internal workings of the application, and user interface design - what the user sees and interacts with.

Program Design

Understand the Problem

Getting started on any project, especially a large and complex program, can be an intimidating task. You need to decide what the purpose of the application will be, what features it will support, how the user interface will look and behave, how the program will be structured, and much more.

However, the first task must always be to understand the problem. If you've been programming for a while, you may have experienced a situation where you sat down with a group of users, defined a problem, and laid out a prototype of a program - only to build the program and be told "Well, that's not really what we wanted."

The way to avoid this common scenario is to completely define the problem before you begin construction of the program. This is, of course, easier said than done. Often the users of an application don't really know what they want the program to do or can't express it in terms that communicate the objective fully. While they may have asked for a contact management program, what they may really want is a tool that allows them to communicate with and sell to their customers more easily and effectively. Perhaps that tool is a contact management system, but it may be something else entirely.

As the application designer, its up to you to make sure that what you're building will do the job that needs to be done.

Break Down the Problem

There are a lot of different ways to go about designing an application, but I've found that what works best for me is to break down the problem into components. By breaking the program down in this manner, you can treat each component as much as possible as an independent entity, making the programming task easier and the application more flexible. If, for example, you are working on a customer database, you might break it down into a data access component, a business rule component, and a user interface component. By handling each component independently, you can change any of the components without needing to redesign the others.

Integrate the Solution

Once you have fully defined the problem and broken it down into independent components, you are ready to begin building and integrating the solution. Start by defining the interfaces between the components. As long as there are well defined and stable interfaces between the components, you can change the internal workings of any component without redesigning the application.

User Interface Design

Introduction

Building a user interface according to accepted standards is the one area where I'll approach the idea of laying out rules for design. Part of the success of Windows and Microsoft applications in particular is due to the common user interface across applications. Users gain a tremendous advantage if they have an idea of how to use an application right from the start. This can only happen if the design of the interface has the look, feel, and functionality of the applications they are already using.

If you're looking for a complete and definitive reference to designing a user interface, you can find it in the MSDN Visual Basic Starter Kit that ships with VB4 Pro (or better) on CD. Under "Product Documentation", open "SDKs" and review the Windows Interface Guidelines for Software Design. I'll just outline a few of the basics here. It's also possible to meet Windows 95 logo requirements using Visual Basic. I've made a copy of a white paper from the Microsoft Visual Basic web site which outlines the logo requirements.

  • Put control in the hands of the users.
    Windows provides a vast array of capabilities for users to customize their environment. Take advantage of this in your applications by using customizations that users have already defined, such as colors, date and time settings, etc. The user can modify these settings through control panel applets. If you use the already defined settings, you not only give the user additional control over the application, you also present a more consistent interface as well as saving yourself the trouble of building an interface for customizing the settings in your app.
  • Use system tools where they are available.
    Using established tools for things such as common dialogs, etc., gives users an advantage of already knowing how to use parts of your application before ever running it.
  • Don't assume that your app is the only program in use.
    Windows is a multi-tasking environment. Users - advanced users in particular - will often be running several applications at once. Keep this fact in mind when you are building your app and make sure that you don't attempt to take over the system. This also means that you should not attempt to control settings that are normally handled by the user, such as display resolution, the window state of the application, etc.
  • Follow established conventions for layout of interface elements.
    The Windows Interface Guidelines for Software Design covers the arrangement of menus and controls in considerable detail. By following the established standards, you can give your application a professional appearance and give the users an extra degree of familiarity with the application.
  • Integrate your application with the operating system.
    Your application should support common operating system extensions, such as properly registering and associating file types with your application, supporting drag and drop if applicable, and supporting mail features.

Coding Standards

I'll state right from the beginning that I don't claim to have developed a set of standards that are right for everyone. Programmers have many varied and strong opinions on coding standards, so you'll have to decide on your own what's right for you. The one thing I will suggest as a key point to remember is that sooner or later, someone else will need to read and understand your code.
  • Layout & Style
  • Coding for Efficiency
  • Modules
  • Procedures

Layout & Style

The main point to remember here is that the layout of your code can have a significant impact on the ability to read it later. While it may be perfectly valid to the compiler to pack five VB statements on a single line or to write a procedure with no indentation, the code will be nearly unreadable to another human - and probably even yourself.

Here's the short version of the layout guidelines I use when writing code:

  • Place a block header comment at the top of each module and procedure.
  • This should outline the purpose, rather than the implementation, of a section of code.
  • Indent properly.
    Indent all the code within a procedure and indent all conditionals and loops. This makes it substantially easier to follow the logic of the code. Additionally, I've redefined the standard indentation to be two characters rather than the default of four. I find two characters to be sufficient to recognize the indentation and allows deeply nested code to be easier to read without horizontal scrolling.
  • Use white space liberally.
    Adding blank lines between sections of code to separate groups of data declarations and blocks of code makes the program easier to read and makes it easier to follow the logic.
  • Use inline comments liberally.
    Add inline comments to describe data declarations and blocks of code. You should also add an inline comment at any point in the program where the purpose of a statement is not entirely obvious. A good guideline to use is that a person should be able to understand the purpose of the code without reading the code, and should be able to understand how the code works without reading the comments. If the former isn't true, you need to add additional comments. If the latter isn't true, you need to rewrite the code to make it less obscure.

Coding for Efficiency

There's been a ton of paper used writing articles on optimizing Visual Basic code, and I'm not going to waste a lot of space repeating that information here. First, you can find it elsewhere easily and second, much of it is often unrelated to the true performance of an application. Here's a short outline of some of the common points that are often made.
  • Avoid the use of variants.
    Variants are generally VB's slowest data type.
  • Use integers where possible.
    Integers and long integers are fast because they are the native data type of the computer hardware.
  • Use variables to represent controls.
    Retrieving and setting control properties is inherently slow. Using a variable reference instead of directly referencing the control in several statements can help improve performance.
  • Use single statement methods rather than a series of property assignments.
    While you can set the Left, Top, Height and Width properties of a text box, its much more efficient to simply use the Move method and reassign all four properties in a single statement.
There are lots of other commonly repeated optimization tips, but like these, many will often have minimal impact on performance. When looking at improving performance in an application, there are two things to consider:
  1. True Performance
    This is the actual speed at which the code is executing and is for the most part completely irrelevant.
  2. Perceived Performance
    This is the performance as perceived by the user.
Frankly, I don't think that the true performance of an application is relevant in the vast majority of cases. What is important is that the user can move efficiently through an application and get their work done. There are two basic ways to increase the perceived performance of an application:
  1. Distract the user during long processes.
    Splash screens, pretty pictures, and progress meters are common tools used to give users something to look at while a long running process is taking place.
  2. Give users something else to do during long processes.
    When possible, you should try to move time consuming tasks into a background process and allow the user to continue with something else while the process is running.
Lets take a closer look at the second item. While VB doesn't provide a means to start background threads in an application, you can use out-of-process OLE servers to hand off long processes. Another technique is to use a "just-in-time" strategy for presenting data. Disk operations are expensive from a performance perspective, even with today's high-speed disks and networks. By delivering only the data that's needed at the time that it's requested, you can minimize disk i/o delays to the user. Caching frequently used disk data is also a method you can use to reduce delays, but take care not to try to store so much disk data in memory that your application becomes a memory hog, forcing the operating system to page additional memory to disk.

Modules

VB4 took a first step into object oriented programming by providing the ability to create class modules. However, you don't necessarily need OOP features in the language to use modules effectively. Modules can be used to consolidate related code and to restrict access to data to those procedures that need it. This allows you to write code which is better organized and allows you to protect your data and avoid the use of global variables.

If you've written any serious applications which used a number of global variables, you've probably also spent some time working out bugs caused by inappropriate access to the global data. By using module level data and access routines for the data which is global in nature, you can control the means used to read and write the data and coordinate related procedures and data.

There are two basic ways to organize the procedures in a module:

  1. Group procedures that use the same data.
    This allows you to protect access to data that is shared by several procedures. Also, since VB loads modules on demand, you can use memory more efficiently by grouping the code that is using the shared data.
  2. Group procedures that perform related tasks.
    If you followed the previous item, this has probably also been done. However, you may have related procedures that don't share any data. For example, I always create a module of procedures that act as wrappers around API functions I use. In these procedures, I handle any setup operations (such as initializing return variables) required. By grouping all the API calls together, I can quickly locate and debug the code.
Another benefit of well organized and self-contained modules is that you can often drop a fully functional module into a new application with little or no modification - saving yourself a considerable amount of coding effort on new projects.

Procedures

I use one rule for coding procedures that has served me well. A procedure should perform one task and do it well. It's often tempting when adding a feature to an application to wrap all of the feature's functionality into a single procedure. The problem with this approach is that you end up with a lot of large, monolithic procedures with a lot of code repeated throughout the application. The result is an application that's hard to debug, maintain, and modify. As an example, I'll illustrate a mistake I made coding an early add-on feature to a database application. Part of a system within the application was a procedure where the end-user would handle a paper application form for a program, do some data entry, approve or deny the application, and then send a letter to the applicant informing them of the status. This was a single step of many in handling these application forms. Other included pre-qualifying applicants and sending blank forms, answering status inquiries, and so on. When I originally organized this sub-system of the main application, I organized the code to follow the steps in the program. For this particular step, the procedure would go through several steps to acquire the necessary data, write a few records to the database, and then used Word to generate either an approval or denial letter. As you can imagine, there were times when failures could occur during the processing. The failures occurred in one of three areas: coding errors, user errors, and physical printing errors (paper jams, etc.). Since the process was written as a monolithic procedure, a failure in any area forced the end user to start the entire procedure from the beginning.

The mistake was really more a design problem than a coding problem. The code was in fact broken down into probably 50 or 60 separate function calls and was fairly well organized. The various functions were for the most part well written and concise. There was a group of functions to manage sending data to and controlling Word, a group of functions to write database records, and several generic utility functions that were used throughout the application. The problem is that the procedure was designed so that it was impossible to generate the letters (the most failure prone part of the procedure) without running the entire procedure.

You can avoid the problems I had if you follow a few simple guidelines in writing procedures:

  • Each procedure should perform only one task.
    Don't consolidate a bunch of unrelated tasks into a procedure just because they happen to occur together in the application.
  • Separate data management from the user interface.
    Write separate procedures to manage data and call them from the user interface code. This allows you to redesign the interface (a more common change) without redesigning the data management code.
  • Give the procedure a clear, simple name that indicates what it does.
    If you can't do this, you probably need to rewrite the code. In my above example, I would have ended up with a procedure name something like this: AquireDataWriteRecordsApproveOrDenyApplicationAndGenerateLetters. If I had rewritten the program, I might have ended up with several small procedures with names like CreateDenialLetter and CreateApprovalLetter being called from other procedures.

Summary

There's a lot more involved in writing good code than the few simple points I've outlined here, but this will give you a start. Keep in mind some of these key points when you're sitting at the keyboard in front of a code window:
  • Understand the problem before you begin building the solution.
  • Follow accepted standards for user interface design.
  • Write code that is readable.
  • Separate user interface and data management.
  • Design for the most efficient use of the program by the user.
  • Design code that can be re-used.
I'll repeat one other piece of advice I gave at the top of the page. Get yourself a copy of Code Complete by Steve McConnell. It's one of the best texts on coding standards that I've read. Although it's not written specifically for Visual Basic, this one book will teach you more about programming (in VB or any other language) than any other book I've read. I have one entire bookshelf dedicated to programming topics, and this is one of about three books that I return to again and again.

Originally written by Joe Garrick

If you enjoyed this post, subscribe for updates (it's free)

just a comment

thanks! you have taught me how to change my coding style for someone else to come and read and understand my code.

Thanks!

Hey, Thanks for sharing. I had the same experience wherein I had to learn to code VB6 on my own. ^_^

think you for your help

think you for your help