Hollsco Group - VBIndent Documentation

About VBIndent

VBIndent began life as a simple code formatting utility for Microsoft QuickBASIC 4.5 and Basic 7.1 PDS. When it was ported to process Visual Basic code, starting with Visual Basic version 3, new features were added, including backups of source files, code and variable profiles, addition of module headers and variable name type identification.

The module headers and variable name type identification were ideas taken from Mark Warhol’s The Art of Programming with Visual Basic, published by John Wiley & Sons, Inc, ISBN 0-471-12853-8. If you write Visual Basic code, or are considering a career programming in any language, you must go to amazon.com and buy this book, now! It is by far the best book of its kind, and you will become a far better and more employable programmer because of reading it. </plug mode off>

Stop! If you do nothing else before running VBIndent, go to the bottom of this document and read the limitations! There aren’t many, but if your program falls into one of them, you may be setting yourself up for problems!

Some things you should note

VBIndent has not been run on every VB6 program ever written. There may be bugs in it, which have not been found while running against your particular VB6 routines. The author is most interested in finding previously overlooked problems that VBIndent has in processing source code. If you find something that VBIndent does incorrectly, please email us at . It would be prudent for you to back up your source code before running VBIndent on it. If VBIndent does something bad to your program, you are responsible. We will do all that is possible to fix the problem in VBIndent, but you need to tell us about it first.

VBIndent was designed to run against VB6 code. It should also have no problems running against VB3, VB4 or VB5 code. VBIndent will not run properly against VB.Net code!

Use at your own risk. Hollsco Group is not liable for unwanted changes, damage or loss to your source code. BACK UP YOUR SOURCE CODE.

What Does It Do?

VBIndent examines your Visual Basic code line by line and makes adjustments to improve readability, ease of maintenance and structure. It is quite capable of taking poorly written code and turning it into easily read, easily maintained code.

Indenting

VBIndent will indent nested loops and structures properly, based on an indentation value that you give it. It will remove multiple blank lines, and insert blank lines where required for readability. It will take lines that contain multiple statements separated by colons, such as:

For Count = 1 To 10: Debug.Print Count: Next Count

And split them apart into readable, structured, nested lines: 

For Count = 1 To 10
  Debug.Print Count
Next Count

More than anything else, this feature turns spaghetti code into readable code. It will also detect nesting errors that the Visual Basic editor cannot. For instance, when Visual Basic encounters the following code:

For Count = 1 To 10
  If a = b Then
    Debug.Print Count
  Next Count
End If

Visual Basic will simply tell you there is an error - somewhere. VBIndent will insert a marker, at the exact line where the coding error occurred:

  ' >>>>>Error - Expected "Else/ElseIf/End If"

If VBIndent reports an error, simply do a search in your code for the text ">>>>>Error" to find the problem.

Formatting Comments

VBIndent will find all comments beginning with "Rem" or a single apostrophe, and will tab all of these comments to a given column, so that all comments in the code line up, making them easier to read. Any comments beginning with "Rem" will be changed to a single apostrophe, for readability. If any line of code runs past the column that the comments are being formatted to, the comment will be extended past the preset column. For this reason, if you wish to return all comments to their original places at the end of each line of code, run VBIndent with the column value set to "1". Any comment that is on a line of its own will be moved to the beginning of the line, rather than the preset column. An example of code, before and after the comment formatting has taken place is shown here:

Before:

For Count = 1 To 10 ' This is a loop
If a = b Then Debug.Print Count: Exit For ' Does a equal b?
Next Count ' We're Done

After:

For Count = 1 To 10        ' This is a loop
  If a = b Then            ' Does a equal b?
    Debug.Print Count
    Exit For
  End If
Next Count                 ' We're Done

Project Backups

If this selection is checked, VBIndent will create a directory off the main project directory called "VBIndent Backup". Each time VBIndent is run, it will copy the old version of each file it has scanned into this directory. After running VBIndent, it is prudent to compile and test your program. If something has happened which causes your program to behave incorrectly, you can copy the original file back in its place. 

Note: The core code modification routines inside VBIndent have been in use and tested worldwide for over ten years. It is highly unlikely VBIndent will make any modifications to your code that will cause it to function differently. If this unlikely situation does occur, please contact the program’s author so the problem can be rectified.

Code Profiles

VBIndent will create a profile of your project when it has completed processing. This profile will help you track which procedures are where, and which variables are being used in which places. The profile will contain details for each module inside the main project file. The profile is generated as an HTML file, as well as an XML file for use in source code management systems.

Module Headers

VBIndent can insert pre-defined module headers into each program module. These headers appear as normal code comments before the module begins:

’ ***********************************************
’ ** Function Name: Testing
’ ** Written By: Amy
’ ** Date Written: 10/29/2001
’ ***********************************************
’ ** This function does nothing of any use
’ ** whatsoever
’ ***********************************************

Public Function Testing (a As Integer) As String

For Count = 1 To 10      ’ This is a loop
  If a = b Then          ’ Does a equal b?
    Debug.Print Count    ’ Print the value
  Next Count
End If                  ’ End of routine

End Function

The Module Headers can be used to specify the date of creation, date of modification, original author, modification history, and so on. VBIndent allows you to customize the header to conform to any requirements or company standards that are currently in use. When this option is selected, VBIndent will automatically pop up the window allowing you to edit the header contents. Edit the contents of the header so that it contains the text you wish inserted at the top of each subroutine. The header text will be inserted as a comment into the code - you do not need to include the single apostrophe or "Rem" statement in front of it. 

Note: VBIndent will not insert header text into any subroutine that already has comments at the top. This is to avoid inserting multiple copies of the header. If you already have comments at the top of a subroutine as shown above, VBIndent will not insert a header there. You can override this option by checking the "Replace Existing Headers" box. If this box is checked, any existing headers on all modules will be lost, and they will be replaced with the header you have specified.

Rename Variables

One of the most powerful functions of VBIndent is its ability to rename variables inside your program. This idea is taken directly from Chapter 1 of Mark Warhol’s The Art of Programming with Visual Basic. VBIndent will allow you to alter the characters used to represent the scope and type of each variable. You may use either upper or lower case characters, from A to Z.

Note: VBIndent will only recognize and alter variables that are explicitly declared with the Dim, Public, Private or Global statements, or passed as arguments into a subroutine, function or property. It is highly recommended that you use the "Option Explicit" feature in Visual Basic to require these declarations. To select this, start Visual Basic, click on "Tools, Options", and select "Require Variable Declaration." This will not affect your current programs - only new programs. You will have to alter your current programs manually to use the Option Explicit feature.

When variables are renamed, VBIndent will insert the scope character, type character, an underscore, and then the previous variable name. A global string variable called UserName could be renamed to GS_UserName. Any variables that are found by VBIndent to begin with two characters and an underscore will be assumed by VBIndent to have been previously renamed, and it will not alter them again. 

DEBUG Mode

With the release of version 6.4, a new feature was added. DEBUG Mode was introduced in response to problems some people had experienced from time to time. VBIndent cannot possibly have been tested against every piece of Visual Basic code ever written, therefore from time to time it would encounter some new type of code that would cause it to lock up and stop processing. Historically, it has been very difficult to determine which code was causing this problem. This has been solved with the new DEBUG Mode.
To activate DEBUG mode, click on the Help menu, and select "Debug". A warning message will appear, and a big red "DEBUG" button will appear on the screen. 

Warning: It is extremely important that you back up your source files before running DEBUG mode! Pressing the DEBUG button will cause VBIndent to stop running, even if it hasn’t finished processing your files, so your files may be left in a partially processed state. BACK UP YOUR SOURCE FILES!!!

To use DEBUG mode, begin processing your files normally. When VBIndent appears to have stopped (the progress bars are no longer moving, and have not reached 100%), click the DEBUG button. A file called Debug.txt will be created in your project directory, and will be displayed in NOTEPAD. Send the contents of this file to to allow us to examine the code causing the problem, and to modify VBIndent to fix the problem. 

VBIndent Limitations

Line Labels

If you have a line label that is not referenced by any GoTo or GoSub statement, and you have other statements following that line label, VBIndent will separate the statements on that line and remove the colon identifying the label as a label. For instance, if you have code identified with a label, which is not referenced by a GoTo or GoSub statement such as this:

Marker: Debug.Print "Hello World"

VBIndent will change it to this:

Marker
Debug.Print "Hello World"

Obviously "Marker" is not a valid Visual Basic statement, and this code will not compile properly. There are three different ways to fix this problem. The first is to make sure that every line label is referenced by a GoTo or GoSub statement:

GoTo Marker

The second is to make sure that all line labels are on lines by themselves:

Marker:
Debug.Print "Hello World"

And the last (and best) way is to remove the line label, and get rid of the GoTo or GoSub statements entirely. Let’s face it - in this age of structured, object-oriented programming, if you’re still writing BASIC code using GoTo or GoSub, you need your head examined!

Constants

When renaming variables, VBIndent will not rename constants. You’ll have to do those yourself. The reason for this is that Visual Basic will determine the most appropriate variable type for each constant, depending on its value, at compile-time. There is no way for VBIndent to know what that type will be, so it leaves constants alone. You may wish to do a global search and replace inside the Visual Basic environment to rename your constants to reflect the renamed variables, both in scope and type.

Implied Variants

When renaming variables, if you declare a variable, or use it in an argument list passed to a subroutine, but do not explicitly declare the type, VBIndent will automatically assume the variable or argument is a Variant, just as Visual Basic does. It is recommended that for code clarity, speed and size, that you explicitly declare the type of all your variables and arguments when declaring them.

Similarly, if you declare a dynamic array without a variable type (which defaults the type to Variant), then later ReDim that array to a specific variable type, VBIndent will not find that redefinition, and will refer to the array throughout the code as a Variant. This is bad coding practice anyway. Always declare your variable types when you declare your variables!

Byte Counts

If you are renaming variables, and have VBIndent set to create a code profile, the byte counts of the final output will be incorrect. The reason for this is that VBIndent generates the code profile on the first pass of the code, therefore any changes made to variable names on the second (renaming) pass are not incorporated into those byte totals. This problem will not occur if you are not renaming variables.

Shared Code

Sometimes you may have individual modules or classes that are used by more than one project. Running VBIndent on one program will modify the shared module, "breaking" the other project. The way around this is to follow this procedure:

1. Make a backup copy of all the shared code.
2. Run VBIndent on the first program.
3. Copy the original shared code back on top of the now-modified code.
4. Run VBIndent on the second program.

VBIndent will modify the shared code identically both times, so that both programs will be referencing the same variables in the module. It is important that you do not change the scope or type settings in VBIndent in between processing the first and second program.

Note: If your classes are properly encapsulated, where the only interfaces to them are Properties, you do not need to do this - VBIndent will not modify property names. However, if you are defining Public variables in your class module to act as properties, these will be modified, and you will need to use the procedure described above.

VBIndent is Copyright 2002 Hollsco Group.
Visual Basic is a trademark of Microsoft Corporation.
This page Copyright 2005 Hollsco Group. All rights reserved.
All specifications subject to change without notice.